HOMSI — End-to-End Taxi Platform
A taxi platform for the Netherlands where I own the Flutter rider and driver clients and the ASP.NET Core backend — REST, SignalR, JWT, and PostGIS dispatch.
- My role
- Full-Stack Developer (rider, driver, backend)
- Period
- April 2026 – Present
- Related experience
- HOMSI
HOMSI is a taxi platform designed for the Netherlands transportation market. My role is unusual: I’m responsible for the full stack — the Flutter rider client, the Flutter driver client, and the ASP.NET Core backend that connects them. When something breaks, I don’t open a ticket and wait; I look at both sides and fix it.
The problem
A ride-hailing product is a real-time, stateful system. A rider needs to watch a driver approach on a live map; a driver needs booking offers pushed instantly with a countdown; the backend needs to find the nearest available driver and manage the lifecycle of a booking from request to payment. Getting this right requires the mobile and backend contracts to fit together precisely.
What I built
Rider app (Flutter). Map-based booking with pickup/destination, server-calculated fare estimation, and a live waiting state powered by SignalR — when a driver accepts, the rider sees the driver’s details and live position animating toward them. Multiple payment methods, trip history, and server-generated PDF receipts.
Driver app (Flutter). Explicit online/offline state controlling the SignalR connection and dispatch pool membership, incoming booking requests with a 30-second countdown, in-app navigation plus deep links to Google Maps/Waze, and battery-aware location broadcasting.
Backend (ASP.NET Core). Clean Architecture with REST APIs (RFC 9457 problem details), two SignalR hubs (rider–driver and dispatch), EF Core + PostgreSQL, and a dispatch state machine driven by a background service for offer timeouts. Nearby-driver lookup uses PostGIS spatial queries with a spatial index. JWT auth with refresh-token rotation and separate claim shapes for riders and drivers.
Technical focus
- Dispatch state machine — booking → offered → accepted/rejected → trip → payment, diagrammed before coding to tame the edge cases.
- Real-time sync — SignalR connection lifecycle, reconnection, and correct connection group routing between a rider and their matched driver.
- PostGIS geo queries — replaced a naive bounding-box “find nearby drivers” with a proper spatial index when driver density grew.
Why full-stack ownership paid off
When a rider’s map didn’t update after “driver accepted,” a Flutter-only view would blame the SignalR subscription and a backend-only view would blame the broadcast. Owning both, I found it in 20 minutes: a connection-group ID mismatch introduced when I renamed the convention on one side and not the other — a cross-cutting bug that would have cost hours as a cross-team coordination problem.
Result
A real-time production system in active development, with one engineer iterating across mobile and backend — the clearest proof of the full-stack positioning I’m building toward.