diff options
| author | soryu <soryu@soryu.co> | 2026-02-16 17:59:38 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-16 17:59:38 +0000 |
| commit | b3de779d87450033f1e0361144c621a1d5f1dbf8 (patch) | |
| tree | 7cb84c2f953bf86f1dd3ec8ff305d70810ac55de /makima/src/server/handlers/orders.rs | |
| parent | 7d2079d7c13804766405af8044574bfc93a86897 (diff) | |
| download | soryu-b3de779d87450033f1e0361144c621a1d5f1dbf8.tar.gz soryu-b3de779d87450033f1e0361144c621a1d5f1dbf8.zip | |
Fix contracts page overflow, remove contract link from orders, add directive name (#65)
* feat: soryu-co/soryu - makima: Add frontend pick-up-orders button and API integration
* WIP: heartbeat checkpoint
* feat: soryu-co/soryu - makima: Remove contract link from orders and add directive name to order metadata (frontend)
* fix: contracts page overflow - use contained scrolling layout
Changed the contracts page to use contained scrolling matching the
orders/directives pages, preventing the page from growing beyond
viewport height.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve completion_task_id FK violation and duplicate button
The completion_task_id column has an FK to tasks(id), but
claim_directive_for_completion was being called with a placeholder UUID
that did not exist in the tasks table, causing FK constraint violations.
Fix: Create the task FIRST via create_task_for_owner, then use the real
task.id when calling claim_directive_for_completion. Applied in all three
locations: phase_completion Part 1 (idle directives), Part 3 (verification
tasks), and trigger_completion_task (manual PR creation).
Also removes a duplicate "Pick Up Orders" button in DirectiveDetail.tsx.
* fix: restore Order type changes lost during rebase conflict resolution
Re-apply changes from the orders-refactor commit that were dropped when
resolving rebase conflicts with --ours:
- Replace contractId with directiveName in Order interface
- Make directiveId required in CreateOrderRequest
- Remove contractId from UpdateOrderRequest
- Change listOrders parameter from contractId to search
- Remove linkOrderToContract function
- Simplify convertOrderToStep to single argument
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'makima/src/server/handlers/orders.rs')
| -rw-r--r-- | makima/src/server/handlers/orders.rs | 85 |
1 files changed, 10 insertions, 75 deletions
diff --git a/makima/src/server/handlers/orders.rs b/makima/src/server/handlers/orders.rs index c43c406..cddf6a6 100644 --- a/makima/src/server/handlers/orders.rs +++ b/makima/src/server/handlers/orders.rs @@ -11,7 +11,7 @@ use axum::{ use uuid::Uuid; use crate::db::models::{ - ConvertToStepRequest, CreateOrderRequest, DirectiveStep, LinkContractRequest, + CreateOrderRequest, DirectiveStep, LinkDirectiveRequest, Order, OrderListQuery, OrderListResponse, UpdateOrderRequest, }; use crate::db::repository; @@ -32,7 +32,7 @@ use crate::server::state::SharedState; ("type" = Option<String>, Query, description = "Filter by order type"), ("priority" = Option<String>, Query, description = "Filter by priority"), ("directive_id" = Option<Uuid>, Query, description = "Filter by directive ID"), - ("contract_id" = Option<Uuid>, Query, description = "Filter by contract ID"), + ("search" = Option<String>, Query, description = "Text search across title, description, and directive name"), ), responses( (status = 200, description = "List of orders", body = OrderListResponse), @@ -62,7 +62,7 @@ pub async fn list_orders( query.order_type.as_deref(), query.priority.as_deref(), query.directive_id, - query.contract_id, + query.search.as_deref(), ) .await { @@ -327,80 +327,13 @@ pub async fn link_to_directive( } } -/// Link an order to a contract. -#[utoipa::path( - post, - path = "/api/v1/orders/{id}/link-contract", - params(("id" = Uuid, Path, description = "Order ID")), - request_body = LinkContractRequest, - responses( - (status = 200, description = "Order linked to contract", body = Order), - (status = 404, description = "Not found", body = ApiError), - (status = 401, description = "Unauthorized", body = ApiError), - (status = 503, description = "Database not configured", body = ApiError), - ), - security(("bearer_auth" = []), ("api_key" = [])), - tag = "Orders" -)] -pub async fn link_to_contract( - State(state): State<SharedState>, - Authenticated(auth): Authenticated, - Path(id): Path<Uuid>, - Json(req): Json<LinkContractRequest>, -) -> impl IntoResponse { - let Some(ref pool) = state.db_pool else { - return ( - StatusCode::SERVICE_UNAVAILABLE, - Json(ApiError::new("DB_UNAVAILABLE", "Database not configured")), - ) - .into_response(); - }; - - // Verify the contract exists and belongs to this owner - match repository::get_contract_for_owner(pool, auth.owner_id, req.contract_id).await { - Ok(Some(_)) => {} - Ok(None) => { - return ( - StatusCode::NOT_FOUND, - Json(ApiError::new("NOT_FOUND", "Contract not found")), - ) - .into_response(); - } - Err(e) => { - return ( - StatusCode::INTERNAL_SERVER_ERROR, - Json(ApiError::new("GET_FAILED", &e.to_string())), - ) - .into_response(); - } - } - - match repository::link_order_to_contract(pool, auth.owner_id, id, req.contract_id).await { - Ok(Some(order)) => Json(order).into_response(), - Ok(None) => ( - StatusCode::NOT_FOUND, - Json(ApiError::new("NOT_FOUND", "Order not found")), - ) - .into_response(), - Err(e) => { - tracing::error!("Failed to link order to contract: {}", e); - ( - StatusCode::INTERNAL_SERVER_ERROR, - Json(ApiError::new("LINK_FAILED", &e.to_string())), - ) - .into_response() - } - } -} - /// Convert an order to a directive step. -/// Creates a new step in the specified directive using the order's title/description, -/// and links the order to both the directive and the new step. +/// Creates a new step in the order's linked directive using the order's title/description, +/// and links the order to the new step. The order must have a directive_id set. #[utoipa::path( post, path = "/api/v1/orders/{id}/convert-to-step", params(("id" = Uuid, Path, description = "Order ID")), - request_body = ConvertToStepRequest, responses( (status = 201, description = "Directive step created from order", body = DirectiveStep), (status = 404, description = "Order or directive not found", body = ApiError), @@ -414,7 +347,6 @@ pub async fn convert_to_step( State(state): State<SharedState>, Authenticated(auth): Authenticated, Path(id): Path<Uuid>, - Json(req): Json<ConvertToStepRequest>, ) -> impl IntoResponse { let Some(ref pool) = state.db_pool else { return ( @@ -424,11 +356,14 @@ pub async fn convert_to_step( .into_response(); }; - match repository::convert_order_to_step(pool, auth.owner_id, id, req.directive_id).await { + match repository::convert_order_to_step(pool, auth.owner_id, id).await { Ok(Some(step)) => (StatusCode::CREATED, Json(step)).into_response(), Ok(None) => ( StatusCode::NOT_FOUND, - Json(ApiError::new("NOT_FOUND", "Order or directive not found")), + Json(ApiError::new( + "NOT_FOUND", + "Order not found or has no linked directive", + )), ) .into_response(), Err(e) => { |
