11"""
22Job management API routes.
33"""
4- from fastapi import APIRouter , Depends , HTTPException , BackgroundTasks , status as api_status , Query
4+ from fastapi import APIRouter , Body , Depends , HTTPException , BackgroundTasks , status as api_status , Query
55from sqlalchemy .orm import Session
66from typing import List , Optional
77from datetime import datetime
88from ...database .connection import get_db , get_db_session
99from ...repositories .job_repository import JobRepository
10- from ...schemas .job import JobNameEnum , JobRunResponse
10+ from ...schemas .job import JobNameEnum , JobRunResponse , TriggerJobRequest
1111from ...jobs import get_job_class
1212from ...utils .logger import get_logger
1313
1818router = APIRouter (prefix = "/jobs" )
1919
2020
21- def execute_job_in_background (job_name : JobNameEnum , job_id : str ):
21+ def execute_job_in_background (job_name : JobNameEnum , job_id : str , params : Optional [ dict ] = None ):
2222 """
2323 Execute a job in the background.
2424
2525 Args:
2626 job_name: The name of the job to execute
2727 job_id: The UUID of the job run to track
28+ params: Optional parameters for the job
2829 """
2930 logger .info (
3031 f"Background task started for job" ,
3132 extra = {
3233 "job_name" : job_name .value ,
33- "job_id" : job_id
34+ "job_id" : job_id ,
35+ "params" : params
3436 }
3537 )
3638
@@ -39,7 +41,7 @@ def execute_job_in_background(job_name: JobNameEnum, job_id: str):
3941 try :
4042 # Get the job class and execute
4143 job_class = get_job_class (job_name )
42- job_class .run (job_id = job_id , db = db )
44+ job_class .run (job_id = job_id , db = db , params = params )
4345 except Exception as e :
4446 logger .error (
4547 f"Background job execution failed" ,
@@ -56,6 +58,65 @@ def execute_job_in_background(job_name: JobNameEnum, job_id: str):
5658def trigger_job (
5759 job_name : JobNameEnum ,
5860 background_tasks : BackgroundTasks ,
61+ request : Optional [TriggerJobRequest ] = Body (
62+ None ,
63+ openapi_examples = {
64+ "no_params" : {
65+ "summary" : "No parameters" ,
66+ "description" : "Run job with default settings" ,
67+ "value" : None
68+ },
69+ "kpi_group_filter" : {
70+ "summary" : "Filter by KPI group" ,
71+ "description" : "Run MCDA analysis for specific KPI group only" ,
72+ "value" : {
73+ "params" : {
74+ "kpi_group_id" : "MCDA_GOALS"
75+ }
76+ }
77+ },
78+ "mcda_regulatory_perspective" : {
79+ "summary" : "MCDA Analysis for regulatory perspective" ,
80+ "description" : "Run MCDA analysis with regulatory stakeholder weights" ,
81+ "value" : {
82+ "params" : {
83+ "kpi_group_id" : "MCDA_GOALS" ,
84+ "perspective" : "regulatory"
85+ }
86+ }
87+ },
88+ "mcda_pto_perspective" : {
89+ "summary" : "MCDA Analysis for PTO perspective" ,
90+ "description" : "Run MCDA analysis with PTO stakeholder weights" ,
91+ "value" : {
92+ "params" : {
93+ "kpi_group_id" : "MCDA_GOALS" ,
94+ "perspective" : "pto"
95+ }
96+ }
97+ },
98+ "mcda_citizens_users_perspective" : {
99+ "summary" : "MCDA Analysis for citizens/users perspective" ,
100+ "description" : "Run MCDA analysis with citizens/users stakeholder weights" ,
101+ "value" : {
102+ "params" : {
103+ "kpi_group_id" : "MCDA_GOALS" ,
104+ "perspective" : "citizens_users"
105+ }
106+ }
107+ },
108+ "mcda_nsm_providers_perspective" : {
109+ "summary" : "MCDA Analysis for NSM providers perspective" ,
110+ "description" : "Run MCDA analysis with NSM providers stakeholder weights" ,
111+ "value" : {
112+ "params" : {
113+ "kpi_group_id" : "MCDA_GOALS" ,
114+ "perspective" : "nsm_providers"
115+ }
116+ }
117+ }
118+ }
119+ ),
59120 db : Session = Depends (get_db )
60121):
61122 """
@@ -67,6 +128,7 @@ def trigger_job(
67128 Args:
68129 job_name: Name of the job to trigger (must be a valid JobNameEnum value)
69130 background_tasks: FastAPI background tasks manager
131+ request: Optional request body with job parameters
70132 db: Database session (injected)
71133
72134 Returns:
@@ -76,8 +138,9 @@ def trigger_job(
76138 HTTPException 404: If the job name is not found in the registry
77139 HTTPException 500: If there's a database error
78140 """
141+ params = request .params if request else None
79142 logger .info (f"Job trigger request received" ,
80- extra = {"job_name" : job_name .value })
143+ extra = {"job_name" : job_name .value , "params" : params })
81144
82145 try :
83146 # Verify the job exists in the registry
@@ -91,21 +154,29 @@ def trigger_job(
91154 )
92155
93156 # Create a new job run with PENDING status
157+ # For MCDA analysis, append perspective to job name if provided
94158 job_repo = JobRepository (db )
95- job_run = job_repo .create_job_run (job_name = job_name .value )
159+ actual_job_name = job_name .value
160+
161+ if job_name == JobNameEnum .MCDA_ANALYSIS and params and "perspective" in params :
162+ perspective = params ["perspective" ]
163+ actual_job_name = f"{ job_name .value } _{ perspective } "
164+ logger .info (f"MCDA job with perspective: { perspective } " )
165+
166+ job_run = job_repo .create_job_run (job_name = actual_job_name )
96167
97168 logger .info (
98169 f"Job run created" ,
99170 extra = {
100- "job_name" : job_name . value ,
171+ "job_name" : actual_job_name ,
101172 "job_id" : job_run .id ,
102173 "status" : job_run .status
103174 }
104175 )
105176
106177 # Schedule the job for background execution
107178 background_tasks .add_task (
108- execute_job_in_background , job_name , job_run .id )
179+ execute_job_in_background , job_name , job_run .id , params )
109180
110181 logger .info (
111182 f"Job scheduled for background execution" ,
0 commit comments