7.7 KiB
7.7 KiB
Job Status Service Plan
Objective
Create a separate reusable library/service that accepts only a job name and returns:
- current
status - parsed
response
The service should use JobModel (jobs table) and align with existing queue statuses used in JobWorker (queued, running, done, failed).
Current Context
JobWorkerwrites job execution data intojobs:- updates
status - updates
run_time - writes JSON-encoded
response
- updates
JobModelis a basic model mapped tojobstable with relevant fields already allowed.
Proposed Design
-
Create a dedicated library class:
- Path:
app/Libraries/JobStatusService.php - Responsibility: read latest job record by
name, normalize output payload.
- Path:
-
Public API of library:
- Method:
getJobStatusByName(string $jobName): array - Input: job name only
- Output contract (example):
success(bool)job_name(string)status(string|null)response(array|string|null)job_id(int|null)uuid(string|null)run_time(float|int|null)message(string)
- Method:
-
Query behavior:
- Search in
jobstable by exactname = $jobName - Order by latest execution (
id DESC) and fetch first row - If no record exists, return
success=falsewith clear message.
- Search in
-
Response normalization:
- Attempt
json_decode(response, true)when response is non-empty. - If decode succeeds, return decoded array/object structure.
- If decode fails or is plain text, return raw response string.
- Keep response key consistent regardless of format.
- Attempt
-
Validation and safety:
- Trim input name and reject empty values.
- Avoid exceptions leaking to caller; wrap unexpected errors and return structured failure response.
Integration Plan
- Keep the library independent from controllers for reuse.
- Optional usage points:
- API controller endpoint can consume the library and return JSON to frontend.
- CLI/debug scripts can consume the same library.
- No changes required in
JobWorkerqueue execution flow for this feature.
Suggested Controller Endpoint (Optional Next Step)
If needed after library creation:
- Add endpoint method (example in
ApiServiceController) acceptingjob_name. - Validate
job_name. - Call
JobStatusService::getJobStatusByName($jobName). - Return JSON response with appropriate HTTP code:
- 200 for found
- 404 for not found
- 422 for invalid input
- 500 for unexpected server errors
Edge Cases
- Multiple jobs with same name: return latest record only.
queued/runningjobs may have empty response; returnresponse=null.- Failed jobs may contain JSON error bundle written by
JobWorker; return decoded details when valid JSON. - Done jobs may return scalar/string payload; preserve as-is when not JSON.
Testing Plan
- Unit-level checks for service method:
- Valid job name with
donestatus and JSON response - Valid job name with
failedstatus and JSON error response - Valid job name with non-JSON response
- Valid job name not found
- Empty job name input
- Valid job name with
- Integration checks (optional):
- Trigger known queue job, then fetch status by name and verify status/response shape.
Deliverables
app/Libraries/JobStatusService.phpwithgetJobStatusByName()method.- (Optional) Controller method + route for API access.
- Minimal usage example in developer notes or inline docblock.
Implementation Steps (Execution Order)
- Create
app/Libraries/JobStatusService.php. - Add constructor or internal setup to initialize
JobModel. - Implement input guard:
- trim
$jobName - return failure payload for empty input.
- trim
- Fetch latest row by
name:where('name', $jobName)->orderBy('id', 'DESC')->first()
- Build normalized response payload:
status,job_id,uuid,run_time,response.
- Decode response safely:
- if empty ->
null - if valid JSON -> decoded array/object
- else -> raw string.
- if empty ->
- Add broad
try/catch (\Throwable $e)and return safe error contract. - (Optional) Wire endpoint in
ApiServiceControllerand route mapping. - Verify manually with one known queued/running job and one completed/failed job.
Payload Contract (Final)
[
'success' => true|false,
'job_name' => (string),
'status' => (string|null), // queued|running|done|failed|null
'response' => (array|string|null),
'job_id' => (int|null),
'uuid' => (string|null),
'run_time' => (float|int|null),
'message' => (string),
]
Error Handling Rules
- Invalid input (
job_nameempty after trim):success=false,message='Job name is required.'
- Not found:
success=false,message='No job record found for given name.'
- Unexpected exception:
success=false,message='Unable to fetch job status right now.'- keep internals/logging server-side only, do not leak stack trace in API response.
Optional Route/Endpoint Mapping
If API exposure is required, prefer a read-only endpoint:
GET /api/job-status?job_name={name}orPOST /api/job-statuswith body{ "job_name": "..." }
Response guidance:
- 200:
success=true - 404: not found
- 422: validation failure
- 500: unexpected server failure
Acceptance Criteria
- Given an existing job
name, service returns latest row by descendingid. statusalways reflects one of existing worker statuses ornull.responseis decoded when valid JSON; otherwise preserved as raw string.- Empty input never triggers DB query and returns validation failure.
- Service never throws unhandled exception to caller.
Non-Goals (Current Scope)
- No change to existing queue insert/update logic in
JobWorker. - No migration/schema change in
jobstable. - No polling/real-time websocket updates in this phase.
Rollout Notes
- Implement service first and test in isolation.
- Add endpoint only if a frontend or external consumer needs it immediately.
- Keep endpoint backward-compatible by not changing existing job payload fields.
- Add lightweight log entry only for unexpected exceptions to aid debugging.
Completed Tasks (Updated)
- Created
app/Libraries/JobStatusService.php. - Added
getJobStatusByName(string $jobName): array. - Implemented empty input validation with structured failure response.
- Implemented latest-record lookup by exact
nameandid DESC. - Implemented response normalization (
null/ decoded JSON / raw string). - Added safe exception handling and server-side error logging.
- Added API endpoint method
ApiServiceController::jobStatus. - Added routes:
GET /jobStatusPOST /jobStatus
- Manual verification against queued/running/done/failed sample jobs (pending).
Route Migration Plan (ApiServiceController -> TestingController)
Objective
Move the jobStatus endpoint ownership from ApiServiceController to TestingController while keeping URL contract unchanged.
Steps
- Add
JobStatusServiceimport inTestingController. - Add
jobStatus()method inTestingControllerwith the same input/output behavior. - Remove
jobStatus()method fromApiServiceControllerto avoid duplicate ownership. - Update route mapping in
Routes.php:GET /jobStatus -> TestingController::jobStatusPOST /jobStatus -> TestingController::jobStatus
- Run syntax checks for updated controller and routes.
Migration Tasks (Updated)
- Added
use App\Libraries\JobStatusService;inTestingController. - Added
TestingController::jobStatus()(GET/POST + JSON fallback). - Removed
ApiServiceController::jobStatus(). - Repointed both
jobStatusroutes toTestingController. - Manual endpoint validation via GET and POST with sample
job_namevalues (pending).