BE improvements
This commit is contained in:
@@ -73,10 +73,7 @@ pub struct TaskAttempt {
|
|||||||
#[derive(Debug, Deserialize, TS)]
|
#[derive(Debug, Deserialize, TS)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
pub struct CreateTaskAttempt {
|
pub struct CreateTaskAttempt {
|
||||||
pub task_id: Uuid,
|
pub executor: Option<String>, // Optional executor name (defaults to "echo")
|
||||||
pub worktree_path: String,
|
|
||||||
pub merge_commit: Option<String>,
|
|
||||||
pub executor: Option<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, TS)]
|
#[derive(Debug, Deserialize, TS)]
|
||||||
@@ -156,9 +153,10 @@ impl TaskAttempt {
|
|||||||
pool: &SqlitePool,
|
pool: &SqlitePool,
|
||||||
data: &CreateTaskAttempt,
|
data: &CreateTaskAttempt,
|
||||||
attempt_id: Uuid,
|
attempt_id: Uuid,
|
||||||
|
task_id: Uuid,
|
||||||
) -> Result<Self, TaskAttemptError> {
|
) -> Result<Self, TaskAttemptError> {
|
||||||
// First, get the task to get the project_id
|
// 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?
|
.await?
|
||||||
.ok_or(TaskAttemptError::TaskNotFound)?;
|
.ok_or(TaskAttemptError::TaskNotFound)?;
|
||||||
|
|
||||||
@@ -167,9 +165,12 @@ impl TaskAttempt {
|
|||||||
.await?
|
.await?
|
||||||
.ok_or(TaskAttemptError::ProjectNotFound)?;
|
.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
|
// Create the worktree using git2
|
||||||
let repo = Repository::open(&project.git_repo_path)?;
|
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
|
// 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)
|
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>""#,
|
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,
|
attempt_id,
|
||||||
data.task_id,
|
task_id,
|
||||||
data.worktree_path,
|
worktree_path_str,
|
||||||
data.merge_commit,
|
Option::<String>::None, // merge_commit is always None during creation
|
||||||
data.executor
|
data.executor
|
||||||
)
|
)
|
||||||
.fetch_one(pool)
|
.fetch_one(pool)
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ pub async fn create_task_attempt(
|
|||||||
Path((project_id, task_id)): Path<(Uuid, Uuid)>,
|
Path((project_id, task_id)): Path<(Uuid, Uuid)>,
|
||||||
Extension(pool): Extension<SqlitePool>,
|
Extension(pool): Extension<SqlitePool>,
|
||||||
Extension(app_state): Extension<crate::app_state::AppState>,
|
Extension(app_state): Extension<crate::app_state::AppState>,
|
||||||
Json(mut payload): Json<CreateTaskAttempt>,
|
Json(payload): Json<CreateTaskAttempt>,
|
||||||
) -> Result<ResponseJson<ApiResponse<TaskAttempt>>, StatusCode> {
|
) -> Result<ResponseJson<ApiResponse<TaskAttempt>>, StatusCode> {
|
||||||
// Verify task exists in project first
|
// Verify task exists in project first
|
||||||
match Task::exists(&pool, task_id, project_id).await {
|
match Task::exists(&pool, task_id, project_id).await {
|
||||||
@@ -127,10 +127,7 @@ pub async fn create_task_attempt(
|
|||||||
|
|
||||||
let id = Uuid::new_v4();
|
let id = Uuid::new_v4();
|
||||||
|
|
||||||
// Ensure the task_id in the payload matches the path parameter
|
match TaskAttempt::create(&pool, &payload, id, task_id).await {
|
||||||
payload.task_id = task_id;
|
|
||||||
|
|
||||||
match TaskAttempt::create(&pool, &payload, id).await {
|
|
||||||
Ok(attempt) => {
|
Ok(attempt) => {
|
||||||
// Start execution asynchronously (don't block the response)
|
// Start execution asynchronously (don't block the response)
|
||||||
let pool_clone = pool.clone();
|
let pool_clone = pool.clone();
|
||||||
|
|||||||
@@ -132,23 +132,11 @@ pub async fn create_task_and_start(
|
|||||||
|
|
||||||
// Create task attempt
|
// Create task attempt
|
||||||
let attempt_id = Uuid::new_v4();
|
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 {
|
let attempt_payload = CreateTaskAttempt {
|
||||||
task_id,
|
|
||||||
worktree_path,
|
|
||||||
merge_commit: None,
|
|
||||||
executor: Some("claude".to_string()), // Default executor
|
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) => {
|
Ok(attempt) => {
|
||||||
// Start execution asynchronously (don't block the response)
|
// Start execution asynchronously (don't block the response)
|
||||||
let pool_clone = pool.clone();
|
let pool_clone = pool.clone();
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ export function ProjectTasks() {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="px-8 overflow-x-scroll my-4">
|
<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
|
<TaskKanbanBoard
|
||||||
tasks={tasks}
|
tasks={tasks}
|
||||||
onDragEnd={handleDragEnd}
|
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 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 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 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, };
|
export type DirectoryEntry = { name: string, path: string, is_directory: boolean, is_git_repo: boolean, };
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user