BE improvements
This commit is contained in:
@@ -73,10 +73,7 @@ pub struct TaskAttempt {
|
||||
#[derive(Debug, Deserialize, TS)]
|
||||
#[ts(export)]
|
||||
pub struct CreateTaskAttempt {
|
||||
pub task_id: Uuid,
|
||||
pub worktree_path: String,
|
||||
pub merge_commit: Option<String>,
|
||||
pub executor: Option<String>,
|
||||
pub executor: Option<String>, // Optional executor name (defaults to "echo")
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, TS)]
|
||||
@@ -156,9 +153,10 @@ impl TaskAttempt {
|
||||
pool: &SqlitePool,
|
||||
data: &CreateTaskAttempt,
|
||||
attempt_id: Uuid,
|
||||
task_id: Uuid,
|
||||
) -> Result<Self, TaskAttemptError> {
|
||||
// First, get the task to get the project_id
|
||||
let task = Task::find_by_id(pool, data.task_id)
|
||||
let task = Task::find_by_id(pool, task_id)
|
||||
.await?
|
||||
.ok_or(TaskAttemptError::TaskNotFound)?;
|
||||
|
||||
@@ -167,9 +165,12 @@ impl TaskAttempt {
|
||||
.await?
|
||||
.ok_or(TaskAttemptError::ProjectNotFound)?;
|
||||
|
||||
// Generate worktree path automatically
|
||||
let worktree_path_str = format!("/tmp/mission-control-worktree-{}", attempt_id);
|
||||
let worktree_path = Path::new(&worktree_path_str);
|
||||
|
||||
// Create the worktree using git2
|
||||
let repo = Repository::open(&project.git_repo_path)?;
|
||||
let worktree_path = Path::new(&data.worktree_path);
|
||||
|
||||
// We no longer store base_commit in the database - it's retrieved live via git2
|
||||
|
||||
@@ -190,9 +191,9 @@ impl TaskAttempt {
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id as "id!: Uuid", task_id as "task_id!: Uuid", worktree_path, merge_commit, executor, created_at as "created_at!: DateTime<Utc>", updated_at as "updated_at!: DateTime<Utc>""#,
|
||||
attempt_id,
|
||||
data.task_id,
|
||||
data.worktree_path,
|
||||
data.merge_commit,
|
||||
task_id,
|
||||
worktree_path_str,
|
||||
Option::<String>::None, // merge_commit is always None during creation
|
||||
data.executor
|
||||
)
|
||||
.fetch_one(pool)
|
||||
|
||||
@@ -113,7 +113,7 @@ pub async fn create_task_attempt(
|
||||
Path((project_id, task_id)): Path<(Uuid, Uuid)>,
|
||||
Extension(pool): Extension<SqlitePool>,
|
||||
Extension(app_state): Extension<crate::app_state::AppState>,
|
||||
Json(mut payload): Json<CreateTaskAttempt>,
|
||||
Json(payload): Json<CreateTaskAttempt>,
|
||||
) -> Result<ResponseJson<ApiResponse<TaskAttempt>>, StatusCode> {
|
||||
// Verify task exists in project first
|
||||
match Task::exists(&pool, task_id, project_id).await {
|
||||
@@ -127,10 +127,7 @@ pub async fn create_task_attempt(
|
||||
|
||||
let id = Uuid::new_v4();
|
||||
|
||||
// Ensure the task_id in the payload matches the path parameter
|
||||
payload.task_id = task_id;
|
||||
|
||||
match TaskAttempt::create(&pool, &payload, id).await {
|
||||
match TaskAttempt::create(&pool, &payload, id, task_id).await {
|
||||
Ok(attempt) => {
|
||||
// Start execution asynchronously (don't block the response)
|
||||
let pool_clone = pool.clone();
|
||||
|
||||
@@ -132,23 +132,11 @@ pub async fn create_task_and_start(
|
||||
|
||||
// Create task attempt
|
||||
let attempt_id = Uuid::new_v4();
|
||||
let worktree_path = format!(
|
||||
"/tmp/task-{}-attempt-{}",
|
||||
task_id,
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis()
|
||||
);
|
||||
|
||||
let attempt_payload = CreateTaskAttempt {
|
||||
task_id,
|
||||
worktree_path,
|
||||
merge_commit: None,
|
||||
executor: Some("claude".to_string()), // Default executor
|
||||
};
|
||||
|
||||
match TaskAttempt::create(&pool, &attempt_payload, attempt_id).await {
|
||||
match TaskAttempt::create(&pool, &attempt_payload, attempt_id, task_id).await {
|
||||
Ok(attempt) => {
|
||||
// Start execution asynchronously (don't block the response)
|
||||
let pool_clone = pool.clone();
|
||||
|
||||
@@ -355,7 +355,7 @@ export function ProjectTasks() {
|
||||
</div>
|
||||
) : (
|
||||
<div className="px-8 overflow-x-scroll my-4">
|
||||
<div className="min-w-[900px] max-w-[2000px] relative">
|
||||
<div className="min-w-[900px] max-w-[2000px] relative py-1">
|
||||
<TaskKanbanBoard
|
||||
tasks={tasks}
|
||||
onDragEnd={handleDragEnd}
|
||||
|
||||
@@ -34,17 +34,17 @@ export type TaskWithAttemptStatus = { id: string, project_id: string, title: str
|
||||
|
||||
export type UpdateTask = { title: string | null, description: string | null, status: TaskStatus | null, };
|
||||
|
||||
export type TaskAttemptStatus = "init" | "setuprunning" | "setupcomplete" | "setupfailed" | "executorrunning" | "executorcomplete" | "executorfailed" | "paused";
|
||||
export type TaskAttemptStatus = "setuprunning" | "setupcomplete" | "setupfailed" | "executorrunning" | "executorcomplete" | "executorfailed";
|
||||
|
||||
export type TaskAttempt = { id: string, task_id: string, worktree_path: string, merge_commit: string | null, executor: string | null, created_at: string, updated_at: string, };
|
||||
|
||||
export type CreateTaskAttempt = { task_id: string, worktree_path: string, merge_commit: string | null, executor: string | null, };
|
||||
export type CreateTaskAttempt = { executor: string | null, };
|
||||
|
||||
export type UpdateTaskAttempt = Record<string, never>;
|
||||
|
||||
export type TaskAttemptActivity = { id: string, task_attempt_id: string, status: TaskAttemptStatus, note: string | null, created_at: string, };
|
||||
export type TaskAttemptActivity = { id: string, execution_process_id: string, status: TaskAttemptStatus, note: string | null, created_at: string, };
|
||||
|
||||
export type CreateTaskAttemptActivity = { task_attempt_id: string, status: TaskAttemptStatus | null, note: string | null, };
|
||||
export type CreateTaskAttemptActivity = { execution_process_id: string, status: TaskAttemptStatus | null, note: string | null, };
|
||||
|
||||
export type DirectoryEntry = { name: string, path: string, is_directory: boolean, is_git_repo: boolean, };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user