@@ -17,7 +17,7 @@ use std::sync::atomic::Ordering;
1717use std:: sync:: Arc ;
1818
1919use crate :: application:: error:: { ApplicationError , ApplicationErrorKind } ;
20- use crate :: application:: { backtests, sweeps, tasks as app_tasks, workflows} ;
20+ use crate :: application:: { backtests, pipeline , sweeps, tasks as app_tasks, workflows} ;
2121use crate :: engine:: walk_forward:: { WalkForwardParams , WfMode , WfObjective } ;
2222use crate :: scripting:: engine:: CachingDataLoader ;
2323use crate :: server:: state:: AppState ;
@@ -302,6 +302,67 @@ pub async fn submit_sweep(
302302 Ok ( Json ( SubmitResponse { task_id } ) )
303303}
304304
305+ /// `POST /tasks/pipeline` — Submit a full pipeline task (sweep + gates + WF + MC).
306+ #[ allow( clippy:: unused_async) ]
307+ pub async fn submit_pipeline (
308+ State ( state) : State < AppState > ,
309+ Json ( req) : Json < SubmitSweepRequest > ,
310+ ) -> Result < Json < SubmitResponse > , ( StatusCode , String ) > {
311+ let symbol = req
312+ . params
313+ . get ( "symbol" )
314+ . and_then ( Value :: as_str)
315+ . unwrap_or ( "pending" )
316+ . to_owned ( ) ;
317+
318+ let params_json =
319+ serde_json:: to_value ( & req. params ) . unwrap_or ( Value :: Object ( serde_json:: Map :: default ( ) ) ) ;
320+
321+ let task = state. task_manager . register (
322+ TaskKind :: Sweep ,
323+ & req. strategy ,
324+ & symbol,
325+ req. thread_id . clone ( ) ,
326+ params_json,
327+ ) ;
328+ let task_id = task. id . clone ( ) ;
329+
330+ let tm = Arc :: clone ( & state. task_manager ) ;
331+ let server = state. server . clone ( ) ;
332+ tokio:: spawn ( async move {
333+ Box :: pin ( app_tasks:: execute_queued_task (
334+ tm,
335+ Arc :: clone ( & task) ,
336+ async move {
337+ let pipeline_req = pipeline:: PipelineRequest {
338+ strategy : req. strategy ,
339+ mode : req. mode ,
340+ objective : req. objective ,
341+ params : req. params ,
342+ sweep_params : req. sweep_params ,
343+ max_evaluations : req. max_evaluations ,
344+ num_permutations : req. num_permutations ,
345+ thread_id : req. thread_id ,
346+ } ;
347+
348+ let result = pipeline:: execute ( & server, & pipeline_req, "manual" )
349+ . await
350+ . map_err ( |e| e. to_string ( ) ) ?;
351+
352+ let result_json = serde_json:: to_value ( & result) . unwrap_or ( Value :: Null ) ;
353+
354+ Ok ( app_tasks:: TaskCompletion {
355+ result_json,
356+ result_id : result. sweep_id ,
357+ } )
358+ } ,
359+ ) )
360+ . await ;
361+ } ) ;
362+
363+ Ok ( Json ( SubmitResponse { task_id } ) )
364+ }
365+
305366/// `POST /tasks/walk-forward` — Submit a walk-forward validation task.
306367#[ allow( clippy:: unused_async, clippy:: too_many_lines) ]
307368pub async fn submit_walk_forward (
0 commit comments