feat(tasks): persist list_id/effort/notes + update_task_cmd — close Task 2 metadata gap
This commit is contained in:
@@ -16,6 +16,7 @@ use kon_storage::{
|
||||
list_subtasks as db_list_subtasks,
|
||||
list_tasks as db_list_tasks,
|
||||
uncomplete_task as db_uncomplete_task,
|
||||
update_task as db_update_task,
|
||||
TaskRow,
|
||||
};
|
||||
|
||||
@@ -30,6 +31,7 @@ pub struct TaskDto {
|
||||
pub bucket: String,
|
||||
pub list_id: Option<String>,
|
||||
pub effort: Option<String>,
|
||||
pub notes: String,
|
||||
pub done: bool,
|
||||
pub done_at: Option<String>,
|
||||
pub created_at: String,
|
||||
@@ -45,6 +47,7 @@ impl From<TaskRow> for TaskDto {
|
||||
bucket: r.bucket,
|
||||
list_id: r.list_id,
|
||||
effort: r.effort,
|
||||
notes: r.notes,
|
||||
done: r.done,
|
||||
done_at: r.done_at,
|
||||
created_at: r.created_at,
|
||||
@@ -60,7 +63,12 @@ pub struct CreateTaskRequest {
|
||||
pub id: String,
|
||||
pub text: String,
|
||||
pub bucket: String,
|
||||
#[serde(default)]
|
||||
pub source_transcript_id: Option<String>,
|
||||
#[serde(default)]
|
||||
pub list_id: Option<String>,
|
||||
#[serde(default)]
|
||||
pub effort: Option<String>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -74,6 +82,8 @@ pub async fn create_task_cmd(
|
||||
&request.text,
|
||||
&request.bucket,
|
||||
request.source_transcript_id.as_deref(),
|
||||
request.list_id.as_deref(),
|
||||
request.effort.as_deref(),
|
||||
)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
@@ -87,6 +97,46 @@ pub async fn create_task_cmd(
|
||||
.ok_or_else(|| format!("Task {} not found after insert", request.id))
|
||||
}
|
||||
|
||||
/// Patch-shaped update. Any field omitted (or explicit `null`) leaves the
|
||||
/// column untouched via `COALESCE` in the storage layer. Matches
|
||||
/// `update_transcript`'s partial-update philosophy. `done` / `doneAt` are
|
||||
/// intentionally absent — those flow through `complete_task_cmd` /
|
||||
/// `uncomplete_task_cmd` to stamp the server-side timestamp.
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UpdateTaskRequest {
|
||||
#[serde(default)]
|
||||
pub text: Option<String>,
|
||||
#[serde(default)]
|
||||
pub bucket: Option<String>,
|
||||
#[serde(default)]
|
||||
pub list_id: Option<String>,
|
||||
#[serde(default)]
|
||||
pub effort: Option<String>,
|
||||
#[serde(default)]
|
||||
pub notes: Option<String>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn update_task_cmd(
|
||||
state: tauri::State<'_, AppState>,
|
||||
id: String,
|
||||
patch: UpdateTaskRequest,
|
||||
) -> Result<TaskDto, String> {
|
||||
let row = db_update_task(
|
||||
&state.db,
|
||||
&id,
|
||||
patch.text.as_deref(),
|
||||
patch.bucket.as_deref(),
|
||||
patch.list_id.as_deref(),
|
||||
patch.effort.as_deref(),
|
||||
patch.notes.as_deref(),
|
||||
)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok(TaskDto::from(row))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn list_tasks_cmd(
|
||||
state: tauri::State<'_, AppState>,
|
||||
|
||||
@@ -258,6 +258,7 @@ pub fn run() {
|
||||
// Tasks (canonical SQLite-backed task CRUD)
|
||||
commands::tasks::create_task_cmd,
|
||||
commands::tasks::list_tasks_cmd,
|
||||
commands::tasks::update_task_cmd,
|
||||
commands::tasks::complete_task_cmd,
|
||||
commands::tasks::delete_task_cmd,
|
||||
commands::tasks::uncomplete_task_cmd,
|
||||
|
||||
Reference in New Issue
Block a user