Delivery & Driver System
Drivers use a web-based interface at /delivery to claim available orders, pick up food, and deliver to customers. The system is claim-based — drivers choose which orders to accept.
Driver Interface
Main page at src/app/delivery/page.tsx (2343 lines):
- Available orders: Unassigned delivery orders with status
acceptedorready - My deliveries: Orders assigned to this driver
- Real-time notifications: Browser push + sound alerts for new orders
- GPS integration: Location tracking for ETA and proof of delivery
Navigation sidebar links to /delivery (active orders) and /delivery/history (past deliveries).
Order Claiming Flow
- Restaurant accepts order → status becomes
accepted - System sends “New delivery available” notification to all drivers
- Driver views available orders at
/api/driver/orders/available - Driver claims order →
POST /api/driver/orders/{id}/claim - System checks max active deliveries (default: 1, configurable via
DRIVER_MAX_ACTIVE_DELIVERIES) - Atomic update: only succeeds if
driver_user_id IS NULL(prevents double-claims) - Notifications sent to customer, restaurant staff, and admins
Admins can also manually assign drivers via PATCH /api/admin/orders/{id}.
Delivery Lifecycle
1. CLAIMED — Driver accepts order (driver_user_id set)
2. PICKED UP — Driver at restaurant, marks pickup
→ Status: out_for_delivery, picked_up_at set
→ Optional: bag verification (pickup_verified_at)
3. DELIVERED — Driver at customer, captures proof
→ Status: delivered, delivered_at set
→ Proof: photo + GPS location + optional signature
Resignation
Drivers can resign before pickup (statuses: accepted, ready):
- Sets
driver_user_id = null - Records
driver_released_at,driver_released_by_uid - Order returns to available pool
Cannot resign after out_for_delivery.
Admin Release
Admins can forcibly unassign a driver. If order was out_for_delivery, it reverts to ready.
Delivery Fee Calculation
src/utils/distance.ts:
Base fee: $3.00 USD
Per-km (beyond 1km): $0.50 USD
Formula: $3 + max(distance - 1, 0) × $0.50
Converted to HNL cents using exchange rate from config
Example: 3km delivery = $3 + (2 × $0.50) = $4.00 USD → ~10,400 HNL cents at 2600 rate.
Distance calculated using haversine formula between restaurant and delivery address coordinates.
ETA Calculation
Two methods:
-
Google Maps Distance Matrix (
/api/driver/eta): Real-time ETA from driver’s current GPS location to restaurant. RequiresGOOGLE_MAPS_SERVER_KEY. -
Simple estimate (
src/utils/distance.ts):max(5, 5 + distance_km × 4)minutes. Used as fallback and for customer-facing estimates.
Customer ETA combines prep time + delivery time (src/utils/eta.ts).
Proof of Delivery
POST /api/driver/orders/{id}/proof:
{
captured_at: string // ISO timestamp
captured_by_uid: string // Driver's auth UID
note?: string // Delivery notes
photo_file_id?: string // Uploaded photo reference
signature_file_id?: string // Customer signature
location?: {
lat: number
lng: number
accuracy_meters?: number
}
}
Photos uploaded via /api/uploads, stored on Cloudflare R2.
Driver Notifications
src/lib/driverNotifications.ts:
- Web Push API with VAPID keys
- Custom alert sound (880Hz + 1108Hz tones)
- Vibration pattern: [120ms, 60ms, 120ms]
- Shows order number, pickup restaurant, dropoff address
API Routes
| Route | Method | Purpose |
|---|---|---|
/api/driver/orders |
GET | List driver’s assigned orders |
/api/driver/orders/available |
GET | List unclaimed delivery orders |
/api/driver/orders/{id}/claim |
POST | Claim an order |
/api/driver/orders/{id}/pickup |
POST | Mark as picked up |
/api/driver/orders/{id}/resign |
POST | Release order |
/api/driver/orders/{id}/proof |
POST | Submit proof of delivery |
/api/driver/eta |
GET | Calculate ETA to restaurant |
/api/driver/max-deliveries |
GET | Get max active delivery limit |
/api/admin/drivers |
GET | List all drivers with busy/idle status |
Key Files
| File | Purpose |
|---|---|
src/app/delivery/page.tsx |
Main driver UI |
src/components/delivery/DriverSidebar.tsx |
Driver navigation |
src/app/api/driver/orders/available/route.ts |
Available orders endpoint |
src/app/api/driver/orders/[orderId]/claim/route.ts |
Order claiming |
src/app/api/driver/orders/[orderId]/pickup/route.ts |
Pickup confirmation |
src/app/api/driver/orders/[orderId]/proof/route.ts |
Proof of delivery |
src/app/api/driver/orders/[orderId]/resign/route.ts |
Order resignation |
src/app/api/driver/eta/route.ts |
ETA calculation |
src/utils/distance.ts |
Haversine distance, delivery fee calc |
src/utils/eta.ts |
Customer ETA estimation |
src/lib/driverNotifications.ts |
Push notifications + sounds |
src/lib/driverLimits.ts |
Max active deliveries config |
src/app/admin/drivers/page.tsx |
Admin driver management |