summaryrefslogtreecommitdiff
path: root/makima/src/db
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/db')
-rw-r--r--makima/src/db/models.rs30
-rw-r--r--makima/src/db/repository.rs60
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(&current.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?;