Skip to content
This repository was archived by the owner on Apr 11, 2026. It is now read-only.

Commit 4698aa7

Browse files
z23ccclaude
andcommitted
feat(service): migrate lifecycle helpers to json_store
Replace load_task, load_epic, load_tasks_for_epic, find_dependents in lifecycle.rs with json_store file reads. Keep get_runtime and status writes via DB (RuntimeState has fields not in TaskState). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6bdbb02 commit 4698aa7

1 file changed

Lines changed: 17 additions & 24 deletions

File tree

flowctl/crates/flowctl-service/src/lifecycle.rs

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -109,42 +109,35 @@ fn validate_task_id(id: &str) -> ServiceResult<()> {
109109
Ok(())
110110
}
111111

112-
/// Load a task from the DB (sole source of truth).
113-
async fn load_task(conn: Option<&Connection>, _flow_dir: &Path, task_id: &str) -> Option<Task> {
114-
let conn = conn?;
115-
let repo = flowctl_db::TaskRepo::new(conn.clone());
116-
repo.get(task_id).await.ok()
112+
/// Load a task from JSON files.
113+
async fn load_task(_conn: Option<&Connection>, flow_dir: &Path, task_id: &str) -> Option<Task> {
114+
flowctl_core::json_store::task_read(flow_dir, task_id).ok()
117115
}
118116

119-
async fn load_epic(conn: Option<&Connection>, _flow_dir: &Path, epic_id: &str) -> Option<Epic> {
120-
let conn = conn?;
121-
let repo = flowctl_db::EpicRepo::new(conn.clone());
122-
repo.get(epic_id).await.ok()
117+
async fn load_epic(_conn: Option<&Connection>, flow_dir: &Path, epic_id: &str) -> Option<Epic> {
118+
flowctl_core::json_store::epic_read(flow_dir, epic_id).ok()
123119
}
124120

125-
async fn get_runtime(conn: Option<&Connection>, task_id: &str) -> Option<RuntimeState> {
121+
async fn get_runtime(conn: Option<&Connection>, _flow_dir: &Path, task_id: &str) -> Option<RuntimeState> {
126122
let conn = conn?;
127123
let repo = flowctl_db::RuntimeRepo::new(conn.clone());
128124
repo.get(task_id).await.ok().flatten()
129125
}
130126

131-
/// Load all tasks for an epic from the DB (sole source of truth).
127+
/// Load all tasks for an epic from JSON files.
132128
async fn load_tasks_for_epic(
133-
conn: Option<&Connection>,
134-
_flow_dir: &Path,
129+
_conn: Option<&Connection>,
130+
flow_dir: &Path,
135131
epic_id: &str,
136132
) -> std::collections::HashMap<String, Task> {
137133
use std::collections::HashMap;
138134

139-
if let Some(conn) = conn {
140-
let task_repo = flowctl_db::TaskRepo::new(conn.clone());
141-
if let Ok(tasks) = task_repo.list_by_epic(epic_id).await {
142-
let mut map = HashMap::new();
143-
for task in tasks {
144-
map.insert(task.id.clone(), task);
145-
}
146-
return map;
135+
if let Ok(tasks) = flowctl_core::json_store::task_list_by_epic(flow_dir, epic_id) {
136+
let mut map = HashMap::new();
137+
for task in tasks {
138+
map.insert(task.id.clone(), task);
147139
}
140+
return map;
148141
}
149142

150143
HashMap::new()
@@ -316,7 +309,7 @@ pub async fn start_task(
316309
}
317310
}
318311

319-
let existing_rt = get_runtime(conn, &req.task_id).await;
312+
let existing_rt = get_runtime(conn, flow_dir, &req.task_id).await;
320313
let existing_assignee = existing_rt.as_ref().and_then(|rt| rt.assignee.clone());
321314

322315
// Validate state machine transition (unless --force)
@@ -449,7 +442,7 @@ pub async fn done_task(
449442
}
450443

451444
// Prevent cross-actor completion (unless --force)
452-
let runtime = get_runtime(conn, &req.task_id).await;
445+
let runtime = get_runtime(conn, flow_dir, &req.task_id).await;
453446
if !req.force {
454447
if let Some(ref rt) = runtime {
455448
if let Some(ref assignee) = rt.assignee {
@@ -685,7 +678,7 @@ pub async fn fail_task(
685678
)));
686679
}
687680

688-
let runtime = get_runtime(conn, &req.task_id).await;
681+
let runtime = get_runtime(conn, flow_dir, &req.task_id).await;
689682
let reason_text = req.reason.unwrap_or_else(|| "Task failed".to_string());
690683

691684
let (final_status, upstream_failed_ids) =

0 commit comments

Comments
 (0)