Skip to main content
Version: RK Auto

Admin Service Request Status Update Feature

[!NOTE] Purpose of this Document: This is a comprehensive technical reference for the Admin Override feature. It details API contracts, database interactions, real-time synchronization, architectural design decisions, and system limitations.


1. Feature Overview​

The Admin Service Request Status Update feature provides system administrators with a high-level override mechanism to forcefully change the state of any service request.

While technicians are bound by a rigid, linear state machine dictated by their mobile application, administrators were originally going to be able to jump states. However, to prevent data corruption and maintain identical lifecycle tracking, administrators are now strictly bound to the exact same step-by-step state machine as technicians (Assigned -> Accepted -> EnRoute -> InProgress -> Completed).

Admins cannot skip steps (e.g., you cannot jump from Accepted directly to InProgress; you must go to EnRoute first). The only exception is Canceled, which can be triggered from any state.


2. API Contract​

PUT /service-requests/{requestId}/status​

Updates the status of a specific service request.

Authorization Requirements:

  • Valid Bearer Token
  • Requires Custom Scope: Right.admin_user using ScopeOperator.And

Request Payload (AdminUpdateServiceRequestStatusRequest)​

{
"Status": "Completed", // ENUM: Pending, EnRoute, InProgress, Canceled, Completed
"Mileage": 15.5, // (Decimal) Required ONLY if Status == "Completed"
"CompletedServices": [ // (List of GUIDs) Required ONLY if Status == "Completed"
"3fa85f64-5717-4562-b3fc-2c963f66afa6"
],
"AdditionalServices": [ // (List of GUIDs) Optional
"2db85f64-5717-4562-b3fc-2c963f66afb7"
],
"Evidences": [ // (List of Strings/URLs) Optional
"https://storage.provider.com/evidence-1.jpg"
]
}

Example Responses​

200 OK (Success)

{
"status": 200,
"message": "Service request status updated successfully"
}

400 Bad Request (Validation Failure)

{
"status": 400,
"message": "Mileage and Completed Services are required when updating status to Completed."
}

403 Forbidden (State Machine Block)

{
"status": 403,
"message": "Admin cannot update status to Assigned directly. Please use the assignment feature."
}

3. System Architecture & Workflow​

The override workflow is centralized within ServiceRequestService.UpdateServiceRequestStatusAdmin.

Sequence Diagram​

sequenceDiagram
actor Admin
participant API as ServiceManagementController
participant Service as ServiceRequestService
participant DAL as ServiceRequestDal
participant TechDAL as TechnicianDal
participant RealTime as RealTimeService (SignalR)
participant Cache as RouteCacheService

Admin->>API: PUT /admin/service-requests/{id}/status
API->>Service: UpdateServiceRequestStatusAdmin()

Note over Service: 1. Validate Admin & Guard 'Assigned' Status
Service->>DAL: GetServiceRequestBasicInfo()

alt Status == Completed
Service->>Service: Validate Mileage & Services
Service->>DAL: CompleteServiceRequestDal()
Service->>Service: CreateInvoiceForCompletedServiceAsync()
else All Other Statuses
Service->>DAL: ForceUpdateServiceRequestStatus()
end

Note over Service, TechDAL: 2. Sync Technician Global State
Service->>TechDAL: UpdateTechnicianAvailabilityStatus()

Note over Service, RealTime: 3. Trigger Side-Effects
alt Is Canceled, Pending, or Completed
Service->>Cache: InvalidateRouteAsync()
Service->>RealTime: BroadcastServiceStopped()
Service->>RealTime: BroadcastTechnicianStatusChangeAsync(Available)
else Is InProgress
Service->>RealTime: BroadcastTechnicianStatusChangeAsync(Servicing)
Service->>RealTime: BroadcastServiceStartedAsync()
Service->>Service: SendPushNotification(Customer)
else Is EnRoute
Service->>RealTime: BroadcastTechnicianStatusChangeAsync(EnRoute)
Service->>Service: BroadcastJourneyStartedEventsAsync()
end

Service-->>API: Return Success
API-->>Admin: 200 OK

4. State Transition Matrix (Case Handling)​

The system automatically manages cleanup and notifications depending on the chosen destination state:

🟢 Forcing Completed​

  • Workflow: Validates that Mileage and CompletedServices are provided in the payload. Calculates the final financial total (Base Services + Additional Services). Executes CompleteServiceRequestDal to log the completion. Automatically generates a system invoice (CreateInvoiceForCompletedServiceAsync).
  • Side-Effects: Frees up the technician (TechnicianAvailabilityStatus.Available), invalidates the route cache, and stops live tracking (BroadcastServiceStopped).
  • Use Case: The technician finished the job but their mobile app crashed or lost connectivity before they could hit "Complete" to generate the invoice.

🔴 Forcing Canceled​

  • Workflow: Uses raw SQL to forcefully update the status to Canceled and stamps the cancelledat timestamp in the database.
  • Side-Effects: If the job was actively EnRoute or InProgress, both the Customer and the Technician receive immediate push notifications ("Admin canceled the request"). Live map tracking is terminated, the route cache is dropped, and the technician is marked Available.
  • Use Case: A customer calls the dispatch office to cancel while a technician is already driving toward them.

🟡 Forcing InProgress​

  • Workflow: Uses raw SQL to update the status to InProgress and stamps startedat. Updates the technician's global availability to Servicing.
  • Side-Effects: Broadcasts BroadcastServiceStartedAsync (updating the web dashboard map) and fires a "Your service has started" push notification to the customer's phone.
  • Use Case: A technician arrived on site and started working, but forgot to hit "Start Job" in the app. The admin corrects the state so the customer is properly informed.

🔵 Forcing EnRoute​

  • Workflow: Updates the status to EnRoute and shifts the technician's global availability to EnRoute.
  • Side-Effects: Fetches the technician's details and triggers BroadcastJourneyStartedEventsAsync. This immediately updates the live tracking map and sends a "Technician is on the way" push notification to the customer.
  • Use Case: A technician called dispatch to confirm they are driving, but their mobile device died. The admin triggers the journey so the customer isn't left waiting blindly.

⚪ Forcing Pending​

  • Workflow: Resets the request entirely using raw SQL.
  • Side-Effects: The assigned technician is stripped of the job and made Available. Tracking broadcasts are killed, and the route cache is wiped.
  • Use Case: A job needs to be completely rescheduled for a future date, destroying the current active tracking session.

5. Architectural Decisions & Differences from Technician Flow​

CharacteristicTechnician Flow (HandleTechnicianWorkAction)Admin Flow (UpdateServiceRequestStatusAdmin)
Authentication StrategyStrictly validates the token belongs to the assigned technician.Validates the token belongs to an Admin. Does not require the Admin to be assigned to the job.
State Machine StrictnessHighly linear. Must progress step-by-step.Exactly the same as technicians. Admins cannot skip steps (e.g., Assigned must go to Accepted, then EnRoute, etc.).
Database StrategyUses heavily abstracted business-layer wrappers.Uses optimized direct SQL overrides (ForceUpdateServiceRequestStatus) to inject specific timestamps (startedat, stoppedat) while forcefully skipping intermediary data checks.

[!TIP] Why separate them? We could have added "admin bypass flags" into the standard technician methods. However, this creates tangled, error-prone code that weakens security. A dedicated admin route keeps the technician pipeline rigidly secure while providing admins a surgical tool to manipulate the database.


6. System Limitations & Guardrails​

To prevent critical system corruption, the Admin Override implements several hardcoded limitations:

[!IMPORTANT] No State Jumping Allowed Admins are blocked from jumping over states (e.g., from Assigned straight to InProgress). They must call the endpoint sequentially for every intermediate step to maintain perfect timestamp integrity and trigger the correct live socket events.

[!IMPORTANT] Cannot Change Status to Assigned Admins are blocked from using this endpoint to select Assigned. Assignment involves a highly complex workflow (allocating calendar slots, sending dispatch push notifications to technicians, checking shift overlaps). Admins must use the dedicated AssignServiceRequestToTechnician feature for assignments.

[!IMPORTANT] Cannot Start or Complete Unassigned Jobs If a job currently has no technician assigned (e.g., TechnicianId is null), the admin is strictly blocked from forcing the status to EnRoute, InProgress, Stopped, or Completed. A job cannot logically progress into an active state if there is no human assigned to execute it.

[!CAUTION] Missing Telemetry on Force-Starts When an admin forces a job to EnRoute, the system successfully broadcasts the journey start. However, if the technician's mobile app is currently turned off or lacks GPS signal, the live customer tracking map will simply show the technician's last known position (a static pin) until their app reconnects to send live telemetry. The admin override cannot artificially produce real-time GPS pings.

7. Affected Files (Code Map)​

  • VanTrackerService/Models/ServiceRequest/ServiceRequest.cs: Added AdminUpdateServiceRequestStatusRequest payload model.
  • VanTrackerService/Controllers/ServiceManagementController.cs: Exposed the PUT /admin/service-requests/{requestId}/status endpoint.
  • VanTrackerService/Services/ServiceRequest/ServiceRequestService.cs: Contains the core orchestration logic inside UpdateServiceRequestStatusAdmin.
  • VanTrackerService/DAL/ServiceRequest/ServiceRequestDal.cs: Contains the ForceUpdateServiceRequestStatus raw SQL injection method.