Selected work Original Hanin Taxi company wordmark

Hanin Taxi

Taxi dispatch is not just a nearest-driver lookup. I founded Hanin Taxi and developed dispatch and monitoring workflows around driver queue order, regional pickup restrictions, and operator control, contributing API, Flutter, and React code alongside the team.

My role
Founder · Product & Software Development
Original development
2023 – 2025
Technical focus
Dispatch, driver locations, map integration
Progression
Graduate capstone → World Bankcard

Stage: internal testing. Originally built with my engineering and design team. The public source and regression tests document the October 2026 AI-assisted restoration, separately from the original product work. Contribution scope →

From a ride request to a completed trip.

Rider booking, driver acceptance, operator visibility, and settlement in 40 seconds.

Recorded in the iOS simulator and web dashboard using test accounts. Edited for pacing, with synthetic English narration and optional captions. No live trip or charge.

Rider, driver, and dispatcher screens.

Actual iOS and web captures of the Fort Lee-to-JFK demo flow: rider quote, driver assignment, and operator dispatch. Demo payments do not charge a real card.

Hanin Taxi rider app showing pickup, destination, fare, and the ride request action
Rider quote & requestRoute-fit map, vehicle tiers, $44.07 fare, payment selection, and request action.
Hanin Taxi driver app showing an assigned trip and the next driver action
Accepted driver pickupAssigned rider, pickup details, map handoff, payment state, and next action.
Hanin Taxi operator dashboard showing active trips, driver assignment, and matching status
Live dispatch operationsDispatchers monitor active requests, assigned drivers, and matching state from the same trip lifecycle.

How a trip moves through the system.

Riders and dispatchers submit requests into the same trip lifecycle. Driver availability, company operating rules, and queue state determine which assignments are eligible before a trip moves through acceptance and completion.

  1. 01

    Request

    The rider submits pickup, destination, and vehicle preference to the API.

  2. 02

    Match

    A backend worker evaluates queued requests against available drivers.

  3. 03

    Accept

    SignalR delivers an offer; the driver responds through the API.

  4. 04

    Travel

    Pickup and trip transitions update the shared trip record.

  5. 05

    Complete

    Completion closes the trip and returns the rider to booking.

Dispatch rules and operator tools.

I worked on APIs and selected Flutter/React implementation, including the admin driver-location map, pickup restrictions, and manual dispatch workflows. I also recruited a React engineer, a Flutter engineer, and a Figma designer and reviewed the team's code.

01

Rotate companies, preserve driver order

Traditional operators had drivers return to base and wait their turn. After comparing nearest-driver matching with that model, I chose company-by-company rotation: company A's first driver, company B's first driver, then each company's second driver. The policy preserves each fleet's queue while distributing company turns, accepting that the nearest car may not be next.

The October 2026 review now implements this policy in a shared matcher, with tests for empty queues, eligibility, cooldowns, and overlapping calls. This is a new implementation of the policy, not recovered original code.

Policy and implementation boundary →
02

Check pickup eligibility before matching

The nearest driver may not be eligible to collect the passenger. I implemented company-specific regional pickup restrictions, including a New Jersey operator's New York pickup constraint, so assignment reflected the company's permitted service area as well as driver location.

03

Give dispatchers visibility and a booking workflow

I developed the React admin map for viewing driver locations and working status, alongside manual dispatch workflows. The current review version displays only API-returned company positions, refreshes every 10 seconds without resetting the viewport, and supports focusing on a driver. Dispatcher-entered bookings feed the matching queue.

04

Separate location visibility from navigation

I tested 5- and 10-second rider-map updates, selected Mapbox for cost constraints, and connected driver navigation to Waze and Google Maps. The current driver's GPS/status timers are 30 seconds, while the rider follows SignalR location events. During pickup, those events can also trigger a Mapbox route request: marker updates and paid routing are different operations.

The original final interval and savings are unverified. The decision record separates current code, historical choices, and a cost model using today's published API rates.

Applying taxi dispatch to restaurant delivery.

I delivered the team-built platform as my M.S. capstone. World Bankcard's interest led to a full-time Software Engineer role, where we explored connecting the dispatch platform to its restaurant application for delivery. The integration remained exploratory, with platform work and validation at the internal-testing stage.

Dispatch, realtime access, and regression tests.

The current demo connects reproduced failures to implementation changes and regression tests. Each link opens the source revision verified by the CI run.

01

Keep dispatch consistent across two API instances

Company rotation preserves driver queue order and skips ineligible candidates. In the PostgreSQL demo, matching and trip-state changes share a database transaction lock; the offer and company cursor commit together. Twenty real-database checks run two independent API processes to verify simultaneous offers, duplicate acceptance, acceptance/cancellation races, rollback, and restart/crash recovery.

The global lock favors correctness over throughput. These are synthetic concurrency checks, not fleet-scale load tests.

02

Keep the quote and settlement consistent

The API checks reproduced a missing cash total and excess precision in the stored fare. Cash is now recorded separately from card and points amounts, and quotes are rounded before confirmation. The isolated flow verifies a $44.07 quote through a $44.07 zero-tip cash settlement, without a real charge.

Quote-to-settlement checks →
03

Make the latest route request win

A request version rejects late route responses after a reset or destination change. Camera fitting accounts for the fare panel and cancels superseded animations; clearing the trip restores a close-up pickup view. The rider suite covers delayed responses, camera bounds, coordinates, and airport eligibility.

04

Exercise operator failures, not just the happy path

A regression test caught a reset that left identity persisted; sign-out now clears local state even when the server request fails. Eighteen desktop/mobile browser cases cover authentication, protected navigation, form access, and recovery, including API-driven map polling and empty/error/retry states.

05

Send committed updates only to the right account

SignalR subscriptions require an active account and a database-derived rider, driver, or company channel. Company note, price, and cancellation requests verify trip ownership. In PostgreSQL mode, controller notifications wait for commit; a failed commit discards them.

Nineteen additional integration assertions use real SignalR connections and a commit-time database fault. They verify denied foreign subscriptions and that a rolled-back note never reaches the driver. This is post-commit buffering, not a durable event outbox.

What has been tested.

The linked GitHub Actions run passed all six jobs, including a real PostgreSQL service with two API processes. Coverage includes 64 backend tests, 39 PostgreSQL/SignalR assertions, 11 rider tests, 3 driver tests, 4 operator unit tests, 18 browser cases, and 10 isolated API checks.

What these checks do not establish

This is a local-only demo with synthetic records. The admin map polls every 10 seconds; it is not continuous streaming and the API does not expose a GPS freshness timestamp. Map browser tests use intercepted positions. The video combines restored-client captures with driver start/completion recaptured against the reviewed .NET 10 API; it is not a fresh native build of the entire public snapshot. Historical map experiments do not establish measured savings. PostgreSQL checks use a fresh schema, not production migrations. Fleet-scale load, cross-instance notification delivery, an event outbox, reconnect recovery, live payments, and full authorization coverage remain open. Full verification record →

Platform stack and demo runtime.

Interfaces

Flutter rider app, Flutter driver app, React operator dashboard

Application

C#, ASP.NET Core / .NET 10, Entity Framework, REST APIs, SignalR

Data & Runtime

PostgreSQL application model, EF Core in-memory demo, Vite

Verification

xUnit, Flutter tests, Playwright, GitHub Actions

Restaurant Ordering & Fulfillment Platform