summaryrefslogtreecommitdiff
path: root/makima/src/server/handlers/directives.rs
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-02-16 15:45:42 +0000
committersoryu <soryu@soryu.co>2026-02-16 15:45:42 +0000
commit7d2079d7c13804766405af8044574bfc93a86897 (patch)
tree05212cb5cd472eff75ed54b9805a1d6ef5c7d922 /makima/src/server/handlers/directives.rs
parent29ec8e53f2acf56fe4a2cd02d352144c697a6afc (diff)
downloadsoryu-7d2079d7c13804766405af8044574bfc93a86897.tar.gz
soryu-7d2079d7c13804766405af8044574bfc93a86897.zip
Add PR button to directives
Diffstat (limited to 'makima/src/server/handlers/directives.rs')
-rw-r--r--makima/src/server/handlers/directives.rs82
1 files changed, 82 insertions, 0 deletions
diff --git a/makima/src/server/handlers/directives.rs b/makima/src/server/handlers/directives.rs
index f03dccf..960da94 100644
--- a/makima/src/server/handlers/directives.rs
+++ b/makima/src/server/handlers/directives.rs
@@ -930,6 +930,88 @@ pub async fn cleanup_tasks(
}
// =============================================================================
+// PR Creation
+// =============================================================================
+
+/// Trigger PR creation or update for a directive.
+#[utoipa::path(
+ post,
+ path = "/api/v1/directives/{id}/create-pr",
+ params(("id" = Uuid, Path, description = "Directive ID")),
+ responses(
+ (status = 200, description = "PR task spawned", body = DirectiveWithSteps),
+ (status = 404, description = "Not found", body = ApiError),
+ (status = 409, description = "Completion task already running", body = ApiError),
+ (status = 503, description = "Database not configured", body = ApiError),
+ ),
+ security(("bearer_auth" = []), ("api_key" = [])),
+ tag = "Directives"
+)]
+pub async fn create_pr(
+ 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 crate::orchestration::directive::trigger_completion_task(
+ pool,
+ &state,
+ id,
+ auth.owner_id,
+ )
+ .await
+ {
+ Ok(_task_id) => {
+ // Return the updated directive with steps
+ match repository::get_directive_with_steps_for_owner(pool, auth.owner_id, id).await {
+ Ok(Some((directive, steps))) => {
+ Json(DirectiveWithSteps { directive, steps }).into_response()
+ }
+ Ok(None) => (
+ StatusCode::NOT_FOUND,
+ Json(ApiError::new("NOT_FOUND", "Directive not found")),
+ )
+ .into_response(),
+ Err(e) => (
+ StatusCode::INTERNAL_SERVER_ERROR,
+ Json(ApiError::new("GET_FAILED", &e.to_string())),
+ )
+ .into_response(),
+ }
+ }
+ Err(e) => {
+ let msg = e.to_string();
+ if msg.contains("not found") {
+ (
+ StatusCode::NOT_FOUND,
+ Json(ApiError::new("NOT_FOUND", &msg)),
+ )
+ .into_response()
+ } else if msg.contains("already running") || msg.contains("already claimed") {
+ (
+ StatusCode::CONFLICT,
+ Json(ApiError::new("COMPLETION_IN_PROGRESS", &msg)),
+ )
+ .into_response()
+ } else {
+ (
+ StatusCode::INTERNAL_SERVER_ERROR,
+ Json(ApiError::new("CREATE_PR_FAILED", &msg)),
+ )
+ .into_response()
+ }
+ }
+ }
+}
+
+// =============================================================================
// Order Pickup
// =============================================================================