Skip to main content

bhtune_server/routes/runs/
mod.rs

1//! `POST /api/runs/preflight` (read-only readiness check), `POST /api/runs` (start a new
2//! tune run), and `POST /api/runs/{id}/cancel` (request its cancellation) -- the write side
3//! of the run-history API `routes::history` reads from.
4//!
5//! The preflight endpoint delegates to the runtime's read-only checks without preparing a
6//! tune. Run startup uses the same preparation and drive path as the CLI, keeping template
7//! lookup, tag derivation, validation, driver connection, and live-tune safety behavior in
8//! one implementation. Transport errors and response projections stay in this adapter.
9//! `crate::active_run` tracks every in-flight run so each can be cancelled independently.
10
11use crate::active_run::RunAlreadyActive;
12use crate::error::{ApiError, ErrorBody, require_present};
13use crate::routes::history::{RunDetailResponse, build_run_detail};
14use crate::state::AppState;
15use axum::extract::{Path, State};
16use axum::http::StatusCode;
17use axum::routing::{post, put};
18use axum::{Json, Router};
19use bhtune_core::ResponseLevel;
20use bhtune_db::SqlitePool;
21use bhtune_db::models::{
22    TuneDriver, TuneOutcome, TuneResultRow, TuneRunRow, WriteKind, WriteReadback,
23};
24use bhtune_driver::OpcDaDriver;
25use bhtune_runtime::cancel::CtrlC;
26use bhtune_runtime::tune::{
27    DriverKind, PidWriteOutcome, controller_pid_for_result, drive, preflight, prepare,
28};
29use chrono::Utc;
30
31mod dto;
32mod handlers;
33mod helpers;
34mod validation;
35
36pub use dto::{
37    PreflightCheckResponse, PreflightResponse, PreflightStatus, PreflightTagReadResponse,
38};
39pub use dto::{StartRunRequest, UpdateNotesRequest, WriteRunRequest};
40pub(crate) use handlers::{
41    __path_cancel_run, __path_delete_notes, __path_preflight_run, __path_revert_run,
42    __path_start_run, __path_update_notes, __path_write_run,
43};
44pub(crate) use handlers::{
45    cancel_run, delete_notes, preflight_run, revert_run, start_run, update_notes, write_run,
46};
47
48pub fn router() -> Router<AppState> {
49    Router::new()
50        .route("/api/runs/preflight", post(preflight_run))
51        .route("/api/runs", post(start_run))
52        .route("/api/runs/{id}/cancel", post(cancel_run))
53        .route(
54            "/api/runs/{id}/notes",
55            put(update_notes).delete(delete_notes),
56        )
57        .route("/api/runs/{id}/write", post(write_run))
58        .route("/api/runs/{id}/revert", post(revert_run))
59}