Full-stack delivery platform · 01 / 09
Capitano
Dispatches store orders to the nearest GPS-verified driver, replacing WhatsApp-group dispatch with geofenced, audited tracking.
- Role
- Backend lead · team project
- Year
- 2026
- Status
- MVP complete
- Platform
- Android · iOS · Web admin

Overview
The project.
Delivery companies in Libya often dispatch through WhatsApp groups: the first driver to reply gets the order, whether or not they're close, and nothing verifies arrival, delivery or the cash a driver is carrying.
Capitano replaces that with one platform: a Laravel API and admin website, and a Flutter app with restaurant, driver and admin roles. I designed and built the backend, from the architecture decisions and OpenAPI contract to dispatch, GPS, money and admin, and the Flutter app was built with my teammate Monther against that contract.
The problem
First-to-reply dispatch sends far-away drivers, nobody can verify where a driver really is or whether an order was delivered, and cash and monthly payouts are tracked by hand.
My solution
Stores pick from drivers who are genuinely nearby based on fresh, plausibility-checked GPS. The chosen driver gets a ringing 45-second offer, arrival and delivery are geofenced and proven, and cash lives in an append-only ledger with audited monthly statements.
What it does
Key features.
- 01
Phone OTP login
Throttled, single-use 6-digit codes, with one bound device per driver and a device key that signs each login.
- 02
Nearest-driver map
A PostGIS radius and freshness search, filtered by licence and cash custody, with an ETA and no phone numbers exposed.
- 03
45-second offers
A high-priority push opens a ringing full-screen offer. Requests expire automatically, and five rejections in a row take a driver offline.
- 04
GPS anti-cheat
Mock-location and rooted devices are quarantined, and pings are checked for accuracy, clock skew and impossible speeds.
- 05
Proof of delivery
Geofenced arrival and delivery, a pickup code from the store with an attempt limit, a private proof photo and the cash amount collected.
- 06
Monitoring and penalties
Alerts for no movement, lateness and stalls, plus a penalty ladder that suspends a driver at a daily limit.
- 07
Money ledger
Custody and earnings in an append-only ledger. Monthly statements go draft, approved, paid, export to Excel and Arabic PDF, and lock once approved.
- 08
Support center
Support tickets with image messages, assignment and transfer between operations staff.
- 09
Admin console
Approvals for drivers and stores, a live map, KPIs, reports and manual assign, reassign and cancel.
Interface
Screens from the real app.

Under the hood
How it's built.
Architecture and the engineering decisions behind it.
01
One API for three roles
A Laravel 13 API under /api/v1 serves restaurants, drivers and admins from one Flutter app (the admin role also runs on the web), documented by an OpenAPI 3.1 contract and fuzzed against it in CI.
02
Tenancy that fails closed
Every tenant table carries a company ID, and the scope throws when no tenant context exists instead of returning every row.
03
Geography in the database
PostgreSQL with PostGIS ranks available drivers with ST_DWithin and ST_Distance, and location pings are partitioned by day with a 90-day retention.
04
Urgent work first
Offers go out on a dedicated urgent Redis queue with high-priority FCM pushes, and a scheduler expires requests every five seconds. Scheduled jobs are idempotent, so a missed run catches up.
05
Decisions written down
Eleven architecture decision records, a written roadmap and a review gate on every phase kept a large build consistent.
Problems solved
Technical challenges.
No double assignment under concurrency
Every path locks order, then driver, then request; accepting is a conditional update, and partial unique indexes allow one pending request per driver and per order. Sixteen race tests pit two real database connections against each other.
GPS you can trust
Fixes are checked under a driver lock for mocking, accuracy, clock skew and speed, and a geofence fix must also prove the ping stream was alive. Refused fixes roll back and record their alert separately.
Money that always adds up
Amounts are integers, rounding happens once per order and is frozen, custody is always the sum of ledger entries, and shortfalls are booked as debt instead of a negative payout.
Location data at volume
Daily partitions are created ahead of time and old ones dropped, with short lock timeouts so maintenance never blocks live traffic.
Development status · MVP complete
What's next.
Everything above is built and working. These parts are planned and not implemented yet:
- A real SMS provider for production login codes
- Customer app and tracking links
- Online payments and POS integration
- Multiple orders per driver and automatic nearest-driver dispatch