summaryrefslogtreecommitdiff
path: root/makima/src/db
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-02-16 17:59:38 +0000
committerGitHub <noreply@github.com>2026-02-16 17:59:38 +0000
commitb3de779d87450033f1e0361144c621a1d5f1dbf8 (patch)
tree7cb84c2f953bf86f1dd3ec8ff305d70810ac55de /makima/src/db
parent7d2079d7c13804766405af8044574bfc93a86897 (diff)
downloadsoryu-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/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?;