You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Visual overview of the jobs API after the admin refresh feature was added. Shows the existing per-job route, the new admin refresh route, the shared services they reuse, and how a single admin trigger fans out into seven child job runs.
3
+
Visual overview of the jobs API after the admin refresh feature was added **and refactored**. Shows the existing per-job route, the new admin refresh route, the shared services they reuse, how a single admin trigger fans out into seven child job runs, and the clean-code improvements applied in the post-feature refactor.
4
+
5
+
---
6
+
7
+
## Refactor summary (post-feature)
8
+
9
+
Six clean-code improvements applied after the initial feature ship — all non-breaking:
10
+
11
+
| Area | What changed |
12
+
|---|---|
13
+
|`services/jobs/base.py`| New `BaseJob` ABC: all 4 job classes extend it; lifecycle (STARTED + FAILURE) is no longer duplicated |
14
+
|`services/jobs/__init__.py`| New `jobs` subpackage exposes `BaseJob` at a single canonical import path |
15
+
|`services/full_impact_refresh_service.py`|`FullImpactRefreshOrchestrator` class groups orchestration helpers; module-level shims keep all imports backward-compatible |
16
+
|`schemas/job_run.py` + `schemas/full_impact_refresh.py`|`schemas/job.py` split into two focused modules; original file is now a compatibility shim |
17
+
|`utils/time.py`|`utc_now()` helper replaces deprecated `datetime.utcnow()` calls across all job and service files |
18
+
|`utils/exceptions.py`|`@translate_errors` decorator converts unhandled exceptions to HTTP 500 on the three `router.*` handlers |
4
19
5
20
## 1. Component overview
6
21
7
-
Highlights what is reused vs. newly introduced. New components added by this feature are tagged `NEW`.
22
+
Highlights what is reused vs. newly introduced. Components added by the feature are tagged `NEW`; refactored components are tagged `REFACTOR`.
`POST /jobs/runs/{job_name}` — unchanged behavior, now using the extracted `resolve_actual_job_name` and `execute_job_in_background` helpers from `job_dispatch_service`.
141
+
`POST /jobs/runs/{job_name}` — unchanged behavior, now using the extracted `resolve_actual_job_name` and `execute_job_in_background` helpers from `job_dispatch_service`. Route handlers are now wrapped by `@translate_errors` (refactored).
96
142
97
143
```mermaid
98
144
sequenceDiagram
99
145
autonumber
100
146
participant Client
101
147
participant Router as jobs.router
102
148
participant Verify as verify_api_key
149
+
participant TE as @translate_errors
103
150
participant Handler as trigger_job
104
151
participant Dispatch as job_dispatch_service
105
152
participant Repo as JobRepository
106
153
participant DB as job_runs table
107
154
participant BG as FastAPI BackgroundTasks
108
-
participant Job as JobClass.run
155
+
participant Base as BaseJob.run
156
+
participant Job as JobClass._execute
109
157
110
158
Client->>Router: POST /jobs/runs/{job_name}<br/>X-Internal-API-Key
Base->>Repo: update_job_status(SUCCESS or FAILURE)
125
177
Repo->>DB: UPDATE job_run
126
178
```
127
179
@@ -211,7 +263,7 @@ sequenceDiagram
211
263
212
264
## 5. Class-level interactions
213
265
214
-
How the new modules collaborate with the existing job classes and repository. Reuse is intentional: the admin orchestration calls the same dispatch helpers as the per-job route.
266
+
How the new modules collaborate with the existing job classes and repository. Reuse is intentional: the admin orchestration calls the same dispatch helpers as the per-job route. Job lifecycle management is now centralised in `BaseJob` (refactored).
0 commit comments