AutoMind
An on-demand car-service platform for the UAE built as four connected surfaces — one mobile app carrying both the customer and the technician, an operations dashboard, and a bilingual website — over a single Laravel API, with AI-written inspections, geofenced dispatch, and AED card payments.

- Role
- Technical lead · Platform architecture · DevSparks team delivery
- Services
- Platform & data architecture · Laravel 12 + MySQL API · Expo app for customers and technicians · React 19 operations dashboard · Next.js 16 bilingual website · AI inspection pipeline · AFS/OPPWA card payments · Geofenced dispatch & push notifications · Arabic-first RTL design system
- Stack
- Laravel 12 · MySQL · Expo SDK 54 · React Native · React 19 · Next.js 16 · TypeScript · TanStack Query · Redux Toolkit · NativeWind · Google Gemini · Groq · AFS / OPPWA · Firebase FCM · Google Maps
- Client
- AutoMind
- Industry
- Automotive Services
- Timeline
- 26 weeks · 2026
01 / Business context
The Problem to Solve
AutoMind's promise is that a certified technician comes to the customer instead of the car going to a workshop. That only holds if four things stay in step: what the customer books, what the technician actually does in the driveway, what the office can see, and what the money says. The product needed all of them built as one bilingual system priced in AED, rather than a customer app with a workshop's paperwork behind it.
AutoMind is a mobile-first car-service platform operating across Dubai, Abu Dhabi, and Sharjah: certified technicians travel to the customer's home, office, or roadside for maintenance, inspection, washing, battery work, and emergency roadside help. We delivered it as four surfaces over one Laravel API and one MySQL database — a bilingual Expo app that carries both the customer and the technician role, a React 19 admin dashboard the operation runs from, and a Next.js 16 marketing and booking site — plus the AI inspection pipeline that turns a technician's checklist into a written vehicle report.
02 / From Scope to Launch
How the Work Moved
The work became clearer through decisions, working increments, and feedback—not a long wait for a final reveal.
07 Steps
Step 01
We started from the job rather than the screens, tracing one order from the customer's booking through dispatch, the technician's work in the field, completion, payment, and the money finally landing with the company — and used that trace to decide what belonged in the API instead of in any one client.
Step 02
We modelled the whole operation relationally in MySQL — orders and their items, service and package catalogues, inspections and their photos, technicians with documents and attendance, areas, promo codes, subscriptions, loyalty points, inventory, expenses, payroll, and payments — and exposed it through one versioned Laravel API with role and permission checks on every route.
Step 03
We built the mobile product as a single Expo codebase with two role-scoped route groups, so the customer app and the technician app share the design system, the API client, the localization, and the push layer instead of drifting apart as two projects.
Step 04
We designed bilingually from the first screen: Arabic and English are peers across the app, dashboard, and website, with native RTL through I18nManager on mobile and locale-routed pages on the web.
Step 05
We scoped the dashboard as the room the business is actually run from — orders by type, technicians and their coverage areas, the service catalogue and pricing, promo codes, complaints, ratings, employees and payroll, expenses, and push campaigns — rather than a reporting layer beside the product.
Step 06
We layered the AI work on top of a system that already worked without it: the inspection score is arithmetic on the checklist, and the written report is a queued two-pass model call that can fail, be retried, or be regenerated without blocking a technician.
Step 07
We integrated the money last and deliberately — AFS/OPPWA card checkout settled by webhook, VAT and promo rates snapshotted per order, and cash the technician collects tracked as a wallet balance the company can reconcile.
03 / Decisions that shaped the product
Key Product Decisions
One API and one database behind all four surfaces
- Business context
- A customer app, a technician app, an admin dashboard, and a marketing site could each have been scoped as its own project with its own backend slice. The pricing, status, and permission rules would then have been written four times.
- Decision
- We built one Laravel API over one MySQL schema as the system of record, and made every surface a client of it — including the website, which reads live services and pricing from the same endpoints the app uses.
- Why
- An order is touched by a customer, a technician, and an admin within the same hour. One authoritative model means a status change, a price, or a permission is defined once, and a new surface is a new client rather than a new source of truth.
Two roles in one mobile codebase, not two apps
- Business context
- Customers and technicians need different screens: one books and tracks, the other accepts jobs, clocks in, logs parts, and collects cash. The obvious route is to ship two separate apps.
- Decision
- We built one Expo codebase with role-scoped route groups, a shared design system and API client, and a splash screen that routes to the customer or technician stack based on the signed-in role.
- Why
- The two roles share far more than they differ on — auth, localization, theming, push, order models, maps. One codebase keeps those aligned by construction and means an RTL fix or a token refresh is fixed once, while the release and store overhead stays at one app instead of two.
Bilingual and RTL as a property of the platform, not a screen
- Business context
- A UAE product can be built in English and translated afterwards. Done that way, Arabic arrives as mirrored layouts that mostly work, content that mostly matches, and a backend that only speaks one language.
- Decision
- We made both languages first-class end to end: translatable service, package, and content records in the database, `Accept-Language` honoured on every API call, native RTL on mobile, and locale-routed pages with hreflang on the web.
- Why
- The Arabic experience has to be the same product, not a mirrored copy — which means the service name, the report, and the notification all have to be Arabic at the source, not translated in the client where only one surface would get it.
Score instantly, write the report on a queue
- Business context
- The AI inspection reads a filled 200-point checklist and dozens of technician photos. Doing that inline would leave a technician waiting on a model call in a customer's driveway, and one bad response would block completing the job.
- Decision
- We split the two: the score and grades are computed arithmetically from the checklist the moment the technician closes it, while the written report runs as a queued two-pass job — a vision model reads the photos in bounded batches, then a text model writes the report grounded in the checklist plus those notes.
- Why
- The number the customer cares about appears immediately and never depends on a model being available, and the narrative report can take its time, fail a batch in isolation, or be regenerated by staff without anyone standing still.
Dispatch by drawn coverage area, not by broadcast
- Business context
- The simple version of dispatch notifies every available technician and lets them race. In a service where the technician drives to the customer, that pushes jobs to people who cannot reach them and quietly loses the ones nobody covers.
- Decision
- We modelled service areas as polygons drawn on a map in the dashboard, attached each technician to their area, and pointed order notifications only at the technicians whose zone actually contains the order's coordinates — flagging anything uncovered as out of working area for an admin.
- Why
- Routing on geography rather than availability keeps notifications meaningful for technicians and turns a gap in coverage into a visible operational fact instead of an order that simply never gets picked up.
Cash in the field made visible as a wallet
- Business context
- When a customer pays cash, the money is in the technician's pocket, not the company's account. Without a record of it, a completed order sits unpaid forever and nobody can answer how much company money is out in the field today.
- Decision
- We modelled cash collection as a technician wallet: the collection is recorded on the order, the balance is what the technician owes, handovers are declared and then confirmed by an admin, and partial collections are supported rather than assumed away.
- Why
- It closes the loop between the order being finished and the business being paid, and it makes the field float a number in the dashboard rather than something reconstructed from receipts at the end of a week.
Money rules snapshotted on the order and settled server-side
- Business context
- Prices, promo codes, and the VAT rate all change over time, and a card payment can succeed after the app has already been closed. Recomputing totals or trusting a client callback would both quietly corrupt the record.
- Decision
- We snapshot the price, discount, and VAT rate onto each order at creation, keep every total server-side, and settle card payments from the AFS/OPPWA webhook — with the client only ever holding a public checkout id and polling for the result.
- Why
- An order stays reproducible for as long as it is stored, changing a VAT setting cannot rewrite last month's invoices, and payment state is decided by the gateway talking to the server rather than by whatever the phone managed to report before it lost signal.
04 / The product in use
What Was Built
Real interfaces across the customer and operational experience.



05 / How it was built
Engineering Decisions
Laravel 12 API on PHP 8.2 over MySQL, using Sanctum for tokens, spatie/laravel-permission for role and permission checks, spatie/laravel-translatable for EN/AR content records, and spatie/laravel-activitylog as an audit trail of admin actions.
One Expo SDK 54 / React Native codebase with expo-router route groups per role, TanStack Query for server state, Zustand for auth and onboarding, NativeWind against a shared token theme, and a biometric gate on cold start.
Customer flows: a four-step booking wizard, saved vehicles and locations, live order tracking, in-app payment, ratings, loyalty points redeemed as single-use promo codes, recurring subscriptions that auto-create orders on a schedule, and an AI assistant that quotes live prices.
Technician flows in the same app: available and nearby jobs, accept and complete with per-item work content and photos, daily check-in/check-out attendance, car inventory with consumption logging, expenses with receipts, a cash wallet with handovers, ratings, and earnings reports.
AI inspection pipeline in Laravel: a vision model reads inspection photos in bounded batches, each labelled with its checkpoint, then a text model writes the structured report from the checklist plus those notes — queued, retryable, staff-regenerable, and token-costed per report.
Every completed inspection carries a UUID, so a report opens on a public link without an account — the shareable artifact a buyer or seller actually needs.
React 19 + Vite admin dashboard covering orders by type (regular, AI inspection, pre-purchase, emergency), technicians, geofenced areas drawn on Google Maps, services and packages, promo codes, customers, complaints, ratings, employees and payroll, expenses, push notifications, reports, and per-permission admin roles.
Next.js 16 bilingual website on next-intl with server-rendered locale pages and hreflang, live service and package pricing from the same API, the booking and emergency flows, and a Groq-backed AI assistant behind a server route.
Firebase Cloud Messaging across all three clients for order transitions, with notification targeting derived from role and coverage area rather than broadcast to everyone.
06 / What changed
Delivered Outcome
AutoMind runs as one platform: the customer app, the technician app, the operations dashboard, and the website all read and write the same orders, prices, and permissions.
Customers book, track step by step, pay by card or cash, and rate a job in one bilingual flow, in AED, across Dubai, Abu Dhabi, and Sharjah.
Technicians work the whole day inside the app — jobs, attendance, parts consumed, expenses, cash collected — instead of reporting it back through calls and messages.
AI inspections return a score the moment the checklist is closed and a written report shortly after, shareable by link without an account.
Cash collected in the field, card settlements, VAT, promo discounts, and loyalty redemptions all reconcile inside the same order record, so the operation can see what it is owed.
Ordinary business changes — a price, a new service or package, a coverage area, a promo code, a push campaign — are made in the dashboard and reach customers without a release.
Facing a similar product challenge?
Bring the problem, the current state, and the outcome you need. We can turn that context into a clear product direction and a workable path to launch.