diff options
Diffstat (limited to 'makima/src/db')
| -rw-r--r-- | makima/src/db/models.rs | 30 | ||||
| -rw-r--r-- | makima/src/db/repository.rs | 60 |
2 files changed, 29 insertions, 61 deletions
diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs index bfed942..2951159 100644 --- a/makima/src/db/models.rs +++ b/makima/src/db/models.rs @@ -2880,8 +2880,8 @@ pub struct UpdateDirectiveStepRequest { // ============================================================================= /// An order — a card-based work item (feature, bug, spike, chore, improvement) -/// similar to GitHub Issues or Linear cards. Orders can be linked to directives -/// or contracts for execution. +/// similar to GitHub Issues or Linear cards. Orders are linked to directives +/// for execution. #[derive(Debug, Clone, FromRow, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct Order { @@ -2901,8 +2901,8 @@ pub struct Order { pub directive_id: Option<Uuid>, /// Linked directive step (optional) pub directive_step_id: Option<Uuid>, - /// Linked contract (optional) - pub contract_id: Option<Uuid>, + /// Denormalized directive name for searchability (auto-populated by DB trigger) + pub directive_name: Option<String>, /// Repository context pub repository_url: Option<String>, pub created_at: DateTime<Utc>, @@ -2920,8 +2920,8 @@ pub struct CreateOrderRequest { pub order_type: Option<String>, #[serde(default = "default_empty_labels")] pub labels: serde_json::Value, - pub directive_id: Option<Uuid>, - pub contract_id: Option<Uuid>, + /// Directive ID is required for new orders. + pub directive_id: Uuid, pub repository_url: Option<String>, } @@ -2942,7 +2942,6 @@ pub struct UpdateOrderRequest { pub labels: Option<serde_json::Value>, pub directive_id: Option<Uuid>, pub directive_step_id: Option<Uuid>, - pub contract_id: Option<Uuid>, pub repository_url: Option<String>, } @@ -2967,8 +2966,8 @@ pub struct OrderListQuery { pub priority: Option<String>, /// Filter by linked directive ID pub directive_id: Option<Uuid>, - /// Filter by linked contract ID - pub contract_id: Option<Uuid>, + /// Text search across title, description, and directive_name (case-insensitive) + pub search: Option<String>, } /// Request body for linking an order to a directive. @@ -2978,17 +2977,4 @@ pub struct LinkDirectiveRequest { pub directive_id: Uuid, } -/// Request body for linking an order to a contract. -#[derive(Debug, Deserialize, ToSchema)] -#[serde(rename_all = "camelCase")] -pub struct LinkContractRequest { - pub contract_id: Uuid, -} - -/// Request body for converting an order to a directive step. -#[derive(Debug, Deserialize, ToSchema)] -#[serde(rename_all = "camelCase")] -pub struct ConvertToStepRequest { - pub directive_id: Uuid, -} diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs index 2ef3fbc..cb6a0c6 100644 --- a/makima/src/db/repository.rs +++ b/makima/src/db/repository.rs @@ -6032,8 +6032,8 @@ pub async fn create_order( sqlx::query_as::<_, Order>( r#" - INSERT INTO orders (owner_id, title, description, priority, status, order_type, labels, directive_id, contract_id, repository_url) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + INSERT INTO orders (owner_id, title, description, priority, status, order_type, labels, directive_id, repository_url) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING * "#, ) @@ -6045,7 +6045,6 @@ pub async fn create_order( .bind(order_type) .bind(&req.labels) .bind(req.directive_id) - .bind(req.contract_id) .bind(&req.repository_url) .fetch_one(pool) .await @@ -6059,7 +6058,7 @@ pub async fn list_orders( type_filter: Option<&str>, priority_filter: Option<&str>, directive_id_filter: Option<Uuid>, - contract_id_filter: Option<Uuid>, + search_filter: Option<&str>, ) -> Result<Vec<Order>, sqlx::Error> { // Build dynamic query with optional filters let mut query = String::from("SELECT * FROM orders WHERE owner_id = $1"); @@ -6081,8 +6080,11 @@ pub async fn list_orders( query.push_str(&format!(" AND directive_id = ${}", param_idx)); param_idx += 1; } - if contract_id_filter.is_some() { - query.push_str(&format!(" AND contract_id = ${}", param_idx)); + if search_filter.is_some() { + query.push_str(&format!( + " AND (title ILIKE ${p} OR description ILIKE ${p} OR directive_name ILIKE ${p})", + p = param_idx + )); let _ = param_idx; // suppress unused warning } query.push_str(" ORDER BY created_at DESC"); @@ -6101,8 +6103,8 @@ pub async fn list_orders( if let Some(d) = directive_id_filter { q = q.bind(d); } - if let Some(c) = contract_id_filter { - q = q.bind(c); + if let Some(s) = search_filter { + q = q.bind(format!("%{}%", s)); } q.fetch_all(pool).await @@ -6151,7 +6153,6 @@ pub async fn update_order( let labels = req.labels.as_ref().unwrap_or(¤t.labels); let directive_id = req.directive_id.or(current.directive_id); let directive_step_id = req.directive_step_id.or(current.directive_step_id); - let contract_id = req.contract_id.or(current.contract_id); let repository_url = req.repository_url.as_deref().or(current.repository_url.as_deref()); sqlx::query_as::<_, Order>( @@ -6159,7 +6160,7 @@ pub async fn update_order( UPDATE orders SET title = $3, description = $4, priority = $5, status = $6, order_type = $7, labels = $8, directive_id = $9, directive_step_id = $10, - contract_id = $11, repository_url = $12, updated_at = NOW() + repository_url = $11, updated_at = NOW() WHERE id = $1 AND owner_id = $2 RETURNING * "#, @@ -6174,7 +6175,6 @@ pub async fn update_order( .bind(labels) .bind(directive_id) .bind(directive_step_id) - .bind(contract_id) .bind(repository_url) .fetch_optional(pool) .await @@ -6219,36 +6219,13 @@ pub async fn link_order_to_directive( .await } -/// Link an order to a contract. -pub async fn link_order_to_contract( - pool: &PgPool, - owner_id: Uuid, - order_id: Uuid, - contract_id: Uuid, -) -> Result<Option<Order>, sqlx::Error> { - sqlx::query_as::<_, Order>( - r#" - UPDATE orders - SET contract_id = $3, updated_at = NOW() - WHERE id = $1 AND owner_id = $2 - RETURNING * - "#, - ) - .bind(order_id) - .bind(owner_id) - .bind(contract_id) - .fetch_optional(pool) - .await -} - /// Convert an order to a directive step. Creates a new DirectiveStep from the order's -/// title and description, links the order to both the directive and the new step, -/// and returns the created step. +/// title and description, links the order to the new step, and returns the created step. +/// Uses the order's existing directive_id (which is required for new orders). pub async fn convert_order_to_step( pool: &PgPool, owner_id: Uuid, order_id: Uuid, - directive_id: Uuid, ) -> Result<Option<DirectiveStep>, sqlx::Error> { // Verify the order exists and belongs to this owner let order = sqlx::query_as::<_, Order>( @@ -6264,6 +6241,12 @@ pub async fn convert_order_to_step( None => return Ok(None), }; + // Get the directive_id from the order (required for new orders, but legacy data may have NULL) + let directive_id = match order.directive_id { + Some(id) => id, + None => return Ok(None), + }; + // Verify the directive exists and belongs to this owner let directive = sqlx::query_as::<_, Directive>( r#"SELECT * FROM directives WHERE id = $1 AND owner_id = $2"#, @@ -6301,17 +6284,16 @@ pub async fn convert_order_to_step( .fetch_one(pool) .await?; - // Link the order to the directive and the new step + // Link the order to the new step sqlx::query( r#" UPDATE orders - SET directive_id = $3, directive_step_id = $4, updated_at = NOW() + SET directive_step_id = $3, updated_at = NOW() WHERE id = $1 AND owner_id = $2 "#, ) .bind(order_id) .bind(owner_id) - .bind(directive_id) .bind(step.id) .execute(pool) .await?; |
