feat(trips): live mid-trip truck load input with Pusher broadcast

- Migration: add current_load_kg (nullable unsigned int) to trips table
- Trip model: add current_load_kg to fillable + integer cast
- New TruckLoadBroadcast event (ShouldBroadcastNow)
  - Channel: private admin.live
  - Event name: truck.load
  - Payload: trip_id, team_id, truck_id, current_load_kg, capacity_kg, is_full
- DriverTripController::updateLoad()
  - PATCH /api/v1/driver/trips/{trip}/update-load
  - Validates status is in_progress, saves current_load_kg, fires broadcast
- Route: PATCH driver/trips/{trip}/update-load registered
- CollectionTeamResource: truck_is_full uses current_load_kg (live estimate)
  with fallback to total_load_kg (authoritative dumpsite weight)
- TripResource: expose current_load_kg field
- Admin Teams card:
  - data-team-id attribute added to each card for Echo targeting
  - Load bar uses current_load_kg when available
  - Echo listener for truck.load event patches load bar + badge in real-time
  - truck-status-badge class added to Collecting/Truck Full spans
This commit is contained in:
Developer
2026-07-02 15:01:44 +08:00
parent 3beafa3ac2
commit 1ee4a049dc
7 changed files with 140 additions and 14 deletions

View File

@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api\V1\Driver;
use App\Http\Controllers\Api\V1\ApiController;
use App\Http\Resources\TripResource;
use App\Events\TruckLoadBroadcast;
use App\Models\Trip;
use App\Models\TripStop;
use App\Services\Trip\TripExecutor;
@@ -153,6 +154,27 @@ class DriverTripController extends ApiController
return $this->ok(new TripResource($trip), 'Arrived at dumpsite');
}
public function updateLoad(Request $request, Trip $trip): JsonResponse
{
$this->authorizeDriver($request, $trip);
$data = $request->validate([
'current_load_kg' => ['required', 'integer', 'min:0', 'max:100000'],
]);
if ($trip->status !== Trip::STATUS_IN_PROGRESS) {
return $this->fail('Load can only be updated while a trip is in progress', null, 422);
}
$trip->forceFill(['current_load_kg' => $data['current_load_kg']])->save();
$trip->loadMissing('truck');
TruckLoadBroadcast::dispatch($trip);
return $this->ok([
'current_load_kg' => $trip->current_load_kg,
], 'Truck load updated');
}
public function releaseLoad(Request $request, Trip $trip): JsonResponse
{
$this->authorizeDriver($request, $trip);