refactoring

This commit is contained in:
pavel 2026-02-11 01:29:23 +01:00
commit 13e17770ca
12 changed files with 634 additions and 598 deletions

179
src/server/tasks.rs Normal file
View file

@ -0,0 +1,179 @@
use axum::{
Json,
extract::{Path, State},
http::StatusCode,
};
use sea_orm::{EntityTrait, QueryOrder, QuerySelect};
use std::sync::Arc;
use uuid::Uuid;
use super::AppState;
use super::auth::AuthenticatedUser;
use crate::domain::tasks::{
self, CreateTaskRequest, RecentRunResponse, TaskResponse, UpdateTaskRequest,
};
pub async fn list_tasks(
_user: AuthenticatedUser,
State(state): State<Arc<AppState>>,
) -> Result<Json<Vec<TaskResponse>>, (StatusCode, String)> {
let tasks = crate::entities::task::Entity::find()
.find_with_related(crate::entities::task_run::Entity)
.order_by_desc(crate::entities::task::Column::CreatedAt)
.all(&state.db)
.await
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
let response = tasks
.into_iter()
.map(|(t, mut runs)| {
runs.sort_by(|a, b| b.created_at.cmp(&a.created_at));
TaskResponse {
id: t.id,
goal: t.goal,
cron: t.cron,
created_at: t.created_at,
runs: runs
.into_iter()
.map(|r| tasks::TaskRunResponse {
id: r.id,
status: r.status,
logs: r.logs,
answer: r.answer,
created_at: r.created_at,
})
.collect(),
}
})
.collect();
Ok(Json(response))
}
pub async fn create_task(
_user: AuthenticatedUser,
State(state): State<Arc<AppState>>,
Json(payload): Json<CreateTaskRequest>,
) -> Result<Json<TaskResponse>, (StatusCode, String)> {
let task_id = Uuid::new_v4();
let new_task = crate::entities::task::ActiveModel {
id: sea_orm::Set(task_id),
goal: sea_orm::Set(payload.goal.clone()),
cron: sea_orm::Set(payload.cron.clone()),
created_at: sea_orm::Set(chrono::Utc::now().into()),
};
use sea_orm::ActiveModelTrait;
new_task
.insert(&state.db)
.await
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
if let Some(cron) = &payload.cron {
let _ = state.scheduler.add_task_job(task_id, cron).await;
} else {
let _ = state.scheduler.remove_task_job(task_id).await;
}
tasks::get_task_inner(task_id, &state.db)
.await
.map(Json)
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
}
pub async fn rerun_task(
_user: AuthenticatedUser,
State(state): State<Arc<AppState>>,
Path(id): Path<Uuid>,
) -> Result<Json<TaskResponse>, (StatusCode, String)> {
let task = crate::entities::task::Entity::find_by_id(id)
.one(&state.db)
.await
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?
.ok_or((StatusCode::NOT_FOUND, "Task not found".to_string()))?;
tasks::execute_agent_run(
&state.db,
&state.scheduler,
&state.config,
task.id,
task.goal,
)
.await
.map(Json)
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
}
pub async fn update_task(
_user: AuthenticatedUser,
State(state): State<Arc<AppState>>,
Path(id): Path<Uuid>,
Json(payload): Json<UpdateTaskRequest>,
) -> Result<Json<TaskResponse>, (StatusCode, String)> {
let mut task: crate::entities::task::ActiveModel =
crate::entities::task::Entity::find_by_id(id)
.one(&state.db)
.await
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?
.ok_or((StatusCode::NOT_FOUND, "Task not found".to_string()))?
.into();
task.goal = sea_orm::Set(payload.goal.clone());
task.cron = sea_orm::Set(payload.cron.clone());
use sea_orm::ActiveModelTrait;
task.update(&state.db)
.await
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
if let Some(cron) = &payload.cron {
let _ = state.scheduler.add_task_job(id, cron).await;
} else {
let _ = state.scheduler.remove_task_job(id).await;
}
tasks::get_task_inner(id, &state.db)
.await
.map(Json)
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
}
pub async fn get_task(
_user: AuthenticatedUser,
Path(id): Path<Uuid>,
State(state): State<Arc<AppState>>,
) -> Result<Json<TaskResponse>, (StatusCode, String)> {
tasks::get_task_inner(id, &state.db)
.await
.map(Json)
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
}
pub async fn get_recent_runs(
_user: AuthenticatedUser,
State(state): State<Arc<AppState>>,
) -> Result<Json<Vec<RecentRunResponse>>, (StatusCode, String)> {
let results = crate::entities::task_run::Entity::find()
.find_also_related(crate::entities::task::Entity)
.order_by_desc(crate::entities::task_run::Column::CreatedAt)
.limit(50)
.all(&state.db)
.await
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
let response = results
.into_iter()
.filter_map(|(run, task_opt)| {
task_opt.map(|task| RecentRunResponse {
id: run.id,
task_id: run.task_id,
goal: task.goal,
status: run.status,
created_at: run.created_at,
})
})
.collect();
Ok(Json(response))
}