summaryrefslogtreecommitdiff
path: root/makima/src/db/repository.rs
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/db/repository.rs')
-rw-r--r--makima/src/db/repository.rs54
1 files changed, 44 insertions, 10 deletions
diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs
index 536bc9b..7387735 100644
--- a/makima/src/db/repository.rs
+++ b/makima/src/db/repository.rs
@@ -654,8 +654,8 @@ pub async fn create_task(pool: &PgPool, req: CreateTaskRequest) -> Result<Task,
let new_depth = parent.depth + 1;
- // Subtasks inherit contract_id from parent
- let contract_id = parent.contract_id.unwrap_or(req.contract_id);
+ // Subtasks inherit contract_id from parent (or use request contract_id if parent has none)
+ let contract_id = parent.contract_id.or(req.contract_id);
// Inherit repo settings if not provided
let repo_url = req.repository_url.clone().or(parent.repository_url);
@@ -669,7 +669,7 @@ pub async fn create_task(pool: &PgPool, req: CreateTaskRequest) -> Result<Task,
(new_depth, contract_id, repo_url, base_branch, target_branch, merge_mode, target_repo_path, completion_action)
} else {
- // Top-level task: depth 0, use contract_id from request
+ // Top-level task: depth 0, use contract_id from request (may be None for branched tasks)
(
0,
req.contract_id,
@@ -689,9 +689,10 @@ pub async fn create_task(pool: &PgPool, req: CreateTaskRequest) -> Result<Task,
INSERT INTO tasks (
contract_id, parent_task_id, depth, name, description, plan, priority,
is_supervisor, repository_url, base_branch, target_branch, merge_mode,
- target_repo_path, completion_action, continue_from_task_id, copy_files
+ target_repo_path, completion_action, continue_from_task_id, copy_files,
+ branched_from_task_id, conversation_state
)
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)
RETURNING *
"#,
)
@@ -711,6 +712,8 @@ pub async fn create_task(pool: &PgPool, req: CreateTaskRequest) -> Result<Task,
.bind(&completion_action)
.bind(&req.continue_from_task_id)
.bind(&copy_files_json)
+ .bind(&req.branched_from_task_id)
+ .bind(&req.conversation_history)
.fetch_one(pool)
.await
}
@@ -1041,8 +1044,8 @@ pub async fn create_task_for_owner(
)));
}
- // Subtasks inherit contract_id from parent
- let contract_id = parent.contract_id.unwrap_or(req.contract_id);
+ // Subtasks inherit contract_id from parent (or use request contract_id if parent has none)
+ let contract_id = parent.contract_id.or(req.contract_id);
// Inherit repo settings if not provided
let repo_url = req.repository_url.clone().or(parent.repository_url);
@@ -1056,7 +1059,7 @@ pub async fn create_task_for_owner(
(new_depth, contract_id, repo_url, base_branch, target_branch, merge_mode, target_repo_path, completion_action)
} else {
- // Top-level task: depth 0, use contract_id from request
+ // Top-level task: depth 0, use contract_id from request (may be None for branched tasks)
(
0,
req.contract_id,
@@ -1076,9 +1079,10 @@ pub async fn create_task_for_owner(
INSERT INTO tasks (
owner_id, contract_id, parent_task_id, depth, name, description, plan, priority,
is_supervisor, repository_url, base_branch, target_branch, merge_mode,
- target_repo_path, completion_action, continue_from_task_id, copy_files
+ target_repo_path, completion_action, continue_from_task_id, copy_files,
+ branched_from_task_id, conversation_state
)
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)
RETURNING *
"#,
)
@@ -1099,6 +1103,8 @@ pub async fn create_task_for_owner(
.bind(&completion_action)
.bind(&req.continue_from_task_id)
.bind(&copy_files_json)
+ .bind(&req.branched_from_task_id)
+ .bind(&req.conversation_history)
.fetch_one(pool)
.await
}
@@ -3678,3 +3684,31 @@ pub async fn get_supervisor_conversation_full(
) -> Result<Option<SupervisorState>, sqlx::Error> {
get_supervisor_state(pool, contract_id).await
}
+
+// =============================================================================
+// Anonymous Task Cleanup Functions
+// =============================================================================
+
+/// Delete stale anonymous tasks (tasks with contract_id = NULL) that:
+/// - Are in a terminal state (done, failed, merged)
+/// - Are older than the specified number of days
+///
+/// Returns the number of deleted tasks.
+pub async fn cleanup_stale_anonymous_tasks(
+ pool: &PgPool,
+ max_age_days: i32,
+) -> Result<i64, sqlx::Error> {
+ let result = sqlx::query(
+ r#"
+ DELETE FROM tasks
+ WHERE contract_id IS NULL
+ AND status IN ('done', 'failed', 'merged')
+ AND created_at < NOW() - INTERVAL '1 day' * $1
+ "#,
+ )
+ .bind(max_age_days)
+ .execute(pool)
+ .await?;
+
+ Ok(result.rows_affected() as i64)
+}