diff options
| author | soryu <soryu@soryu.co> | 2026-02-07 16:36:19 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-02-07 16:36:19 +0000 |
| commit | 1b72449496ce3a057a43d002c8042d5e7a1d6576 (patch) | |
| tree | f9151df7cc5128499ee91aafde3ff3c3b3281c1e /makima/src/server/handlers/directives.rs | |
| parent | 9e9f18884c78c21f5785908fb7ccd00e2fa5436b (diff) | |
| download | soryu-1b72449496ce3a057a43d002c8042d5e7a1d6576.tar.gz soryu-1b72449496ce3a057a43d002c8042d5e7a1d6576.zip | |
Add directive init mechanism
Diffstat (limited to 'makima/src/server/handlers/directives.rs')
| -rw-r--r-- | makima/src/server/handlers/directives.rs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/makima/src/server/handlers/directives.rs b/makima/src/server/handlers/directives.rs index a74f8ff..560151b 100644 --- a/makima/src/server/handlers/directives.rs +++ b/makima/src/server/handlers/directives.rs @@ -13,6 +13,7 @@ use crate::db::models::{ DirectiveListResponse, DirectiveWithChains, UpdateDirectiveRequest, }; use crate::db::repository::{self, RepositoryError}; +use crate::orchestration; use crate::server::auth::Authenticated; use crate::server::messages::ApiError; use crate::server::state::SharedState; @@ -438,3 +439,60 @@ pub async fn get_chain( Json(ChainWithSteps { chain, steps }).into_response() } + +/// Start a directive: create a planning contract and begin orchestration. +#[utoipa::path( + post, + path = "/api/v1/directives/{id}/start", + params( + ("id" = Uuid, Path, description = "Directive ID") + ), + responses( + (status = 200, description = "Directive started", body = Directive), + (status = 400, description = "Directive not in draft status", body = ApiError), + (status = 401, description = "Unauthorized", body = ApiError), + (status = 404, description = "Directive not found", body = ApiError), + (status = 503, description = "Database not configured", body = ApiError), + (status = 500, description = "Internal server error", body = ApiError), + ), + security( + ("bearer_auth" = []), + ("api_key" = []) + ), + tag = "Directives" +)] +pub async fn start_directive( + State(state): State<SharedState>, + Authenticated(auth): Authenticated, + Path(id): Path<Uuid>, +) -> impl IntoResponse { + let Some(ref pool) = state.db_pool else { + return ( + StatusCode::SERVICE_UNAVAILABLE, + Json(ApiError::new("DB_UNAVAILABLE", "Database not configured")), + ) + .into_response(); + }; + + match orchestration::directive::init_directive(pool, &state, auth.owner_id, id).await { + Ok(directive) => Json(directive).into_response(), + Err(e) if e.contains("not found") => ( + StatusCode::NOT_FOUND, + Json(ApiError::new("NOT_FOUND", e)), + ) + .into_response(), + Err(e) if e.contains("must be in 'draft'") => ( + StatusCode::BAD_REQUEST, + Json(ApiError::new("INVALID_STATUS", e)), + ) + .into_response(), + Err(e) => { + tracing::error!("Failed to start directive {}: {}", id, e); + ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiError::new("START_FAILED", e)), + ) + .into_response() + } + } +} |
