feat: rider visibility and tracking for the express console
A client login could list its own bookings but had no way to see what its riders were actually doing. jupiter's console gave them getridersummary and the rider/delivery logs; Doormile records all of it and exposed none of it. New console endpoints, all tenant-scoped: GET /admin/milers/summary roster with live state + range totals GET /admin/milers/:id/logs GPS trail from the Redis telemetry index GET /admin/milers/:id/activity one rider's assignments, duty and breaks GET /admin/consignments/:id/logs event history + telemetry + proof GET /admin/bookings/:id/track booking -> assignments -> parcel -> proof Also closes a rider IDOR: GetMilers scoped the roster to the caller's own fleet, but reading, editing, blocking, notifying or assigning a vehicle to a single rider by id did not, so a client login could walk the whole network's riders by incrementing the id. All five now go through assertMilerAccess. And the client dashboard no longer reports milers/customers/exceptions as zero — those have no tenant column, so they are counted through appusers, bookings and consignments respectively. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -250,8 +250,13 @@ func RegisterRoutes(app *fiber.App, cfg *config.Config) {
|
||||
|
||||
// Milers
|
||||
adminAuth.Get("/milers", controllers.GetMilers)
|
||||
// Registered before /milers/:id — Fiber matches in registration order, so
|
||||
// the literal path has to come first or ":id" swallows "summary".
|
||||
adminAuth.Get("/milers/summary", controllers.GetMilerSummary)
|
||||
adminAuth.Post("/milers", controllers.CreateMiler)
|
||||
adminAuth.Get("/milers/:id", controllers.GetMilerDetails)
|
||||
adminAuth.Get("/milers/:id/logs", controllers.GetMilerLogs)
|
||||
adminAuth.Get("/milers/:id/activity", controllers.GetMilerActivity)
|
||||
adminAuth.Put("/milers/:id", controllers.UpdateMiler)
|
||||
adminAuth.Put("/milers/:id/block", controllers.BlockMiler)
|
||||
adminAuth.Put("/milers/:id/assign-vehicle", controllers.AssignMilerVehicle)
|
||||
@@ -262,6 +267,7 @@ func RegisterRoutes(app *fiber.App, cfg *config.Config) {
|
||||
adminAuth.Post("/expressbooking", middlewares.CityGateMiddleware, controllers.CreateExpressBooking)
|
||||
adminAuth.Post("/expressbooking/bulk", middlewares.CityGateMiddleware, controllers.AdminBulkCreateBookings)
|
||||
adminAuth.Get("/bookings/:id", controllers.GetAdminBookingDetails)
|
||||
adminAuth.Get("/bookings/:id/track", controllers.GetAdminBookingTrack)
|
||||
adminAuth.Post("/bookings/:id/assign-miler", controllers.AdminAssignMiler)
|
||||
adminAuth.Post("/bookings/:id/assign-vehicle", controllers.AdminAssignVehicle)
|
||||
adminAuth.Put("/bookings/:id/status", controllers.AdminUpdateBookingStatus)
|
||||
@@ -271,6 +277,7 @@ func RegisterRoutes(app *fiber.App, cfg *config.Config) {
|
||||
// Consignments
|
||||
adminAuth.Get("/consignments", controllers.GetAdminConsignments)
|
||||
adminAuth.Get("/consignments/:id", controllers.GetAdminConsignmentDetails)
|
||||
adminAuth.Get("/consignments/:id/logs", controllers.GetAdminConsignmentLogs)
|
||||
adminAuth.Get("/consignments/track/:trackingno", controllers.GetAdminConsignmentTracking)
|
||||
adminAuth.Put("/consignments/:id/status", controllers.AdminUpdateConsignmentStatus)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user