Document ID: FF-MANUAL-FLEET-OPERATOR-001
Role: FLEET_OPERATOR
Version: 1.0.0
Last Updated: 2026-07-11
Audience: Dispatch coordinators, shift supervisors, real-time fleet operations staff
The Fleet Operator is the real-time dispatch coordinator for FleetFlow operations. This role monitors live driver telemetry, manages driver shift states (AVAILABLE, ON_TRIP, OFFLINE), intervenes in stalled BullMQ matching queues, performs manual dispatch overrides when automation fails, and maintains fleet vehicle maintenance logs.
Fleet Operators are the first responders for dispatch incidents. They work under Head of Warehouse direction for physical hub flow and report matching anomalies to Regional Managers.
| Permission | Granted | Operational Meaning |
|---|---|---|
orders:read:all |
Yes | View every order regardless of merchant |
drivers:manage |
Yes | Change driver status, onboard support actions |
fleet:manage |
Yes | Telemetry dashboards, queue ops, maintenance logs |
orders:cancel |
No | Escalate to Head of Warehouse or Regional Manager |
ledger:read |
No | No financial report access |
merchants:manage |
No | No merchant configuration |
Email: fleet.operator@fleetflow.dev
Password: FleetFlow!2026
Role: FLEET_OPERATOR
Endpoint: POST /v1/auth/login
{
"email": "fleet.operator@fleetflow.dev",
"password": "FleetFlow!2026",
"role": "FLEET_OPERATOR"
}| URL | Purpose |
|---|---|
/fleet/map |
Real-time driver position map |
/fleet/drivers |
Driver list with status filters |
/fleet/queue |
BullMQ dispatch-queue monitor |
/fleet/orders |
All orders with status filters |
/fleet/maintenance |
Vehicle maintenance log |
/fleet/shifts |
Shift schedule management |
Phase 1: Fleet Operator uses API endpoints, Prisma Studio (read-only), and health checks until ops UI ships.
| Field | Source | Refresh Rate |
|---|---|---|
driver.id |
PostgreSQL drivers table |
On query |
driver.fullName |
PostgreSQL | Static |
driver.status |
AVAILABLE | ON_TRIP | OFFLINE |
Real-time (Phase 2: 30s push) |
driver.currentLat |
GPS sync (Phase 2) or last known | 30–60s |
driver.currentLng |
GPS sync (Phase 2) or last known | 30–60s |
vehicle.type |
Joined vehicles table |
Static |
vehicle.plateNumber |
Joined vehicles table |
Static |
activeOrderId |
Orders where assignedDriverId = driver.id and status not terminal |
Real-time |
Map view features:
- Driver pins color-coded by status:
- Green:
AVAILABLE - Blue:
ON_TRIP - Gray:
OFFLINE
- Green:
- Order pickup pins for
PENDINGandMATCHINGorders. - 10 km radius circle around pending pickups showing eligible driver coverage.
- Click driver pin → side panel: name, vehicle, status, last GPS update, active order.
Endpoint: GET /v1/fleet/drivers?status=AVAILABLE&hubId=WH-BKL-001
{
"drivers": [
{
"id": "uuid",
"fullName": "Alex Rivera",
"status": "AVAILABLE",
"currentLat": -6.2012,
"currentLng": 106.8175,
"vehicleType": "BIKE",
"plateNumber": "B-1001-FF",
"lastLocationAt": "2026-07-11T10:15:30.000Z",
"activeOrderId": null
}
],
"total": 1,
"page": 1
}| Activity | Frequency | Action Threshold |
|---|---|---|
| Scan fleet map | Every 15 minutes during shift | Any hub zone with zero AVAILABLE drivers |
| Check GPS freshness | Every 30 minutes | lastLocationAt > 5 minutes stale while AVAILABLE |
| Review ON_TRIP duration | Hourly | Trip > 2 hours without DELIVERED (Phase 2) |
| Match distance audit | Daily | Avg matchDistanceKm > 7 km indicates poor positioning |
- Identify driver with stale coordinates (AVAILABLE but old
lastLocationAt). - Send push notification: "Please open FleetFlow app to refresh location."
- If no response in 10 minutes → call driver.
- If still stale → set status
OFFLINEuntil app confirms fresh GPS. - Log incident in shift notes.
OFFLINE → AVAILABLE → ON_TRIP → AVAILABLE → OFFLINE
↑ |
└──── DELIVERED ───────┘
| Transition | Trigger | Who Initiates |
|---|---|---|
→ AVAILABLE |
Shift start, trip complete | Driver app or Fleet Operator |
→ ON_TRIP |
Matching processor assigns order | System (automatic) |
→ OFFLINE |
Break, end of shift, maintenance | Driver app or Fleet Operator |
ON_TRIP → AVAILABLE |
Delivery complete (Phase 2) | Driver app |
| Shift | Hours (WIB) | Minimum Staff |
|---|---|---|
| Morning | 06:00–14:00 | 2 BIKE, 1 CAR, 1 Fleet Operator |
| Afternoon | 14:00–22:00 | 3 BIKE, 2 CAR, 1 TRUCK, 1 Fleet Operator |
| Night | 22:00–06:00 | On-call only (Bengkulu pilot: no night ops) |
- Review scheduled drivers for shift.
- Call/text each driver: confirm attendance.
- As drivers arrive, verify status →
AVAILABLEin system. - Confirm GPS permissions active on driver devices.
- Report fleet count to Head of Warehouse: "Shift start: 4 BIKE, 2 CAR AVAILABLE."
Endpoint (Phase 2): PATCH /v1/fleet/drivers/:id/status
{
"status": "OFFLINE",
"reason": "Vehicle breakdown — flat tire",
"operatorNote": "Fleet Op Jane — shift 14:00"
}When to override (without driver action):
| Situation | Override To | Reason Code |
|---|---|---|
| Driver phone dead | OFFLINE |
NO_DEVICE_CONTACT |
| Vehicle breakdown | OFFLINE |
VEHICLE_MAINTENANCE |
| Driver no-show | OFFLINE |
NO_SHOW |
| System stuck ON_TRIP after delivery | AVAILABLE |
MANUAL_TRIP_RESET |
| Emergency reassignment needed | AVAILABLE |
OPS_OVERRIDE |
Audit requirement (Phase 2): Every manual override logs operatorId, timestamp, reason.
- Verify no drivers stuck in
ON_TRIP(escalate incomplete deliveries). - Confirm all departing drivers set to
OFFLINE. - Report final fleet count to Head of Warehouse.
- Complete shift handover notes (open queue issues, maintenance flags).
| Component | Value |
|---|---|
| Queue name | dispatch-queue |
| Job name | dispatch-order |
| Worker | MatchingProcessor |
| Broker | Redis 7 (port 6379) |
| Retry policy | 3 attempts, exponential backoff 2000ms base |
| Job ID format | dispatch-order:{orderId} |
- Merchant creates order → status
PENDING→ job enqueued. - Worker picks up job (< 1s typical).
- Status →
MATCHING→ Haversine search →ASSIGNEDorCANCELLED. - Job completes;
removeOnComplete: truedeletes job record.
Expected total duration: < 3 seconds (p95).
Step 1 — API health check:
curl http://localhost:3000/v1/health/ready
# Expected: { "status": "ready", "service": "fleetflow-api" }Step 2 — Redis connectivity:
docker exec fleetflow-redis redis-cli ping
# Expected: PONGStep 3 — Queue depth (Phase 2):
GET /v1/ops/queues/dispatch
{
"queue": "dispatch-queue",
"waiting": 3,
"active": 1,
"completed": 1247,
"failed": 2,
"delayed": 0
}| Symptom | Diagnosis | Resolution |
|---|---|---|
waiting count growing, active = 0 |
Worker not consuming | Restart fleetflow-api container |
active stuck > 30s |
Worker hung on DB query | Check Postgres connections; restart API |
failed count increasing |
Repeated matching errors | Inspect failed job payload in Redis; check logs |
Orders PENDING > 5s, queue empty |
Enqueue failure | Verify Redis; check API logs for BullMQ connection error |
All jobs completed but orders still PENDING |
Status update failure | Database transaction issue — escalate SUPERADMIN |
When order is stuck in PENDING or MATCHING without terminal resolution:
Endpoint: POST /v1/orders/:id/requeue
Auth: FLEET_OPERATOR JWT
- Verify order status is
PENDINGorMATCHING(notASSIGNED). - Check failed job log for prior attempts.
- Execute requeue → new
dispatch-orderjob enqueued. - Monitor order timeline for
MATCHING→ terminal state within 5s. - If second requeue fails → escalate to Regional Manager.
Phase 1 workaround: Contact SUPERADMIN to manually restart API worker and verify Redis.
When automated Haversine matching selects suboptimal driver or fails incorrectly:
Endpoint: POST /v1/orders/:id/assign
{
"driverId": "target-driver-uuid",
"operatorNote": "Manual assign — closest automated driver had vehicle breakdown",
"overrideReason": "DRIVER_BREAKDOWN"
}Preconditions:
- Target driver is
AVAILABLE - Vehicle type matches
order.vehicleTypeRequired - Driver within 10 km radius (warning if override exceeds — requires supervisor approval)
Jobs exhausted after 3 retries move to dead-letter queue dispatch-queue-dlq.
DLQ procedure:
- Review DLQ daily at shift start.
- For each failed job: inspect
orderId, error message, attempt count. - Fix root cause (DB, Redis, invalid order data).
- Requeue from DLQ or cancel order with merchant notification.
Track vehicle condition, scheduled service, and breakdown incidents to ensure driver safety and matching reliability. Poorly maintained vehicles cause OFFLINE spikes and matching deficits.
Endpoint: POST /v1/fleet/vehicles/:id/maintenance
{
"vehicleId": "uuid",
"type": "BREAKDOWN",
"description": "Flat tire — front right. Driver Alex Rivera.",
"reportedAt": "2026-07-11T14:30:00.000Z",
"reportedBy": "fleet-operator-user-id",
"estimatedRepairHours": 4,
"driverId": "driver-uuid",
"actionTaken": "Driver set OFFLINE. Backup driver assigned to pending orders."
}| Maintenance Type | Description |
|---|---|
SCHEDULED_SERVICE |
Oil change, tire rotation, inspection |
BREAKDOWN |
Unplanned failure during shift |
ACCIDENT |
Collision or damage incident |
INSPECTION_PASS |
Routine safety check passed |
INSPECTION_FAIL |
Vehicle removed from fleet until repaired |
- Driver or Fleet Operator reports issue.
- Fleet Operator creates maintenance log entry.
- Set affected driver to
OFFLINE. - Notify Head of Warehouse if inbound/outbound capacity impacted.
- Track repair progress; update log with resolution timestamp.
- On repair complete: inspection pass → driver returns
AVAILABLE.
| Vehicle Type | Service Interval | Inspection Interval |
|---|---|---|
| BIKE | Every 3,000 km | Weekly |
| CAR | Every 5,000 km | Weekly |
| TRUCK | Every 10,000 km | Bi-weekly |
Fleet Operator receives automated reminders 7 days before service due (Phase 3).
When vehicle is in maintenance:
- Linked driver must be
OFFLINE. - Vehicle excluded from matching pool.
- Regional Manager notified if fleet deficit exceeds threshold.
- Maintenance log referenced in cancellation analysis reports.
Fleet Operator views all orders with filters:
| Filter | Use Case |
|---|---|
status=MATCHING |
Active matching in progress |
status=PENDING |
Awaiting worker pickup — stall detection |
status=ASSIGNED + age > 30min |
Driver not picking up at warehouse |
status=CANCELLED + today |
Daily cancellation review |
vehicleTypeRequired=TRUCK |
Low-supply vehicle monitoring |
Endpoint: GET /v1/orders/:id
Review timeline array for diagnostic sequence:
[
{ "status": "DRAFT", "note": "Order draft created and priced.", "createdAt": "..." },
{ "status": "PENDING", "note": "Order queued for driver matching.", "createdAt": "..." },
{ "status": "MATCHING", "note": "Searching for available driver within 10 km radius.", "createdAt": "..." },
{ "status": "CANCELLED", "note": "No available driver within 10 km matching window.", "createdAt": "..." }
]Time deltas between entries reveal bottleneck location.
- Confirm via
GET /v1/health/readyand RedisPING. docker compose restart fleetflow-api(if dockerized) orpnpm dev:apirestart.- Monitor queue depth for 5 minutes.
- Requeue all
PENDINGorders older than 60 seconds. - Notify Regional Manager and affected merchants if outage > 5 minutes.
- Check order timeline.
- Verify matching processor logs for
orderId. - Requeue single order.
- If fails → manual assignment override (Phase 2).
- Look up driver by name or ID.
- Review active order and timeline.
- Coordinate with Head of Warehouse for physical issues.
- Document in shift notes.
- Login to ops console
- Verify
GET /v1/health/ready= ready - Check BullMQ queue depth = 0 waiting
- Confirm scheduled drivers are
AVAILABLE - Review DLQ for overnight failures (Phase 2)
- Brief with Head of Warehouse on inbound staging
- Monitor fleet map every 15 minutes
- Respond to stalled
PENDINGorders within 5 minutes - Process maintenance reports within 30 minutes
- Execute tasks assigned by Head of Warehouse
- Zero orders in
PENDINGorMATCHING(or hand off with notes) - All drivers accounted for (
OFFLINEor completing final trip) - Maintenance log updated
- Handover notes to next Fleet Operator
| Term | Definition |
|---|---|
| BullMQ | Redis-backed job queue for dispatch matching |
| DLQ | Dead-letter queue for failed jobs after max retries |
| Requeue | Re-submit dispatch job for stalled order |
| Telemetry | Live driver GPS and status data |
| Haversine | 10 km radius matching formula |
Document owner: Platform SRE · Next review: 2026-08-11