huskies: merge 492_story_remove_filesystem_pipeline_state_and_store_story_content_in_database
This commit is contained in:
@@ -134,15 +134,10 @@ pub(super) fn tool_get_story_todos(args: &Value, ctx: &AppContext) -> Result<Str
|
||||
.ok_or("Missing required argument: story_id")?;
|
||||
|
||||
let root = ctx.state.get_project_root()?;
|
||||
let current_dir = root.join(".huskies").join("work").join("2_current");
|
||||
let filepath = current_dir.join(format!("{story_id}.md"));
|
||||
|
||||
if !filepath.exists() {
|
||||
return Err(format!("Story file not found: {story_id}.md"));
|
||||
}
|
||||
|
||||
let contents =
|
||||
fs::read_to_string(&filepath).map_err(|e| format!("Failed to read story file: {e}"))?;
|
||||
// Read from DB content store, falling back to filesystem.
|
||||
let contents = crate::http::workflow::read_story_content(&root, story_id)
|
||||
.map_err(|_| format!("Story file not found: {story_id}.md"))?;
|
||||
|
||||
let story_name = parse_front_matter(&contents).ok().and_then(|m| m.name);
|
||||
let todos = parse_unchecked_todos(&contents);
|
||||
@@ -451,7 +446,13 @@ pub(super) async fn tool_delete_story(args: &Value, ctx: &AppContext) -> Result<
|
||||
crate::worktree::remove_worktree_by_story_id(&project_root, story_id, &config).await;
|
||||
}
|
||||
|
||||
// 4. Find and delete the story file from any pipeline stage
|
||||
// 4. Delete from database content store and CRDT.
|
||||
let found_in_db = crate::db::read_content(story_id).is_some()
|
||||
|| crate::crdt_state::read_item(story_id).is_some();
|
||||
|
||||
crate::db::delete_item(story_id);
|
||||
|
||||
// Also delete filesystem file if it exists (backwards compat).
|
||||
let sk = project_root.join(".huskies").join("work");
|
||||
let stage_dirs = [
|
||||
"1_backlog",
|
||||
@@ -461,18 +462,18 @@ pub(super) async fn tool_delete_story(args: &Value, ctx: &AppContext) -> Result<
|
||||
"5_done",
|
||||
"6_archived",
|
||||
];
|
||||
let mut deleted = false;
|
||||
let mut deleted_from_fs = false;
|
||||
for stage in &stage_dirs {
|
||||
let path = sk.join(stage).join(format!("{story_id}.md"));
|
||||
if path.exists() {
|
||||
fs::remove_file(&path).map_err(|e| format!("Failed to delete story file: {e}"))?;
|
||||
let _ = fs::remove_file(&path);
|
||||
slog_warn!("[delete_story] Deleted '{story_id}' from work/{stage}/");
|
||||
deleted = true;
|
||||
deleted_from_fs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if !deleted {
|
||||
if !found_in_db && !deleted_from_fs {
|
||||
return Err(format!(
|
||||
"Story '{story_id}' not found in any pipeline stage."
|
||||
));
|
||||
@@ -948,11 +949,13 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(result.contains("1_bug_login_crash"));
|
||||
assert!(result.contains("_bug_login_crash"), "result should contain bug ID: {result}");
|
||||
// Extract the actual bug ID from the result message (format: "Created bug: <id>").
|
||||
let bug_id = result.trim_start_matches("Created bug: ").trim();
|
||||
let bug_file = tmp
|
||||
.path()
|
||||
.join(".huskies/work/1_backlog/1_bug_login_crash.md");
|
||||
assert!(bug_file.exists());
|
||||
.join(format!(".huskies/work/1_backlog/{bug_id}.md"));
|
||||
assert!(bug_file.exists(), "expected bug file at {}", bug_file.display());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1071,11 +1074,13 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(result.contains("1_spike_compare_encoders"));
|
||||
assert!(result.contains("_spike_compare_encoders"), "result should contain spike ID: {result}");
|
||||
// Extract the actual spike ID from the result message (format: "Created spike: <id>").
|
||||
let spike_id = result.trim_start_matches("Created spike: ").trim();
|
||||
let spike_file = tmp
|
||||
.path()
|
||||
.join(".huskies/work/1_backlog/1_spike_compare_encoders.md");
|
||||
assert!(spike_file.exists());
|
||||
.join(format!(".huskies/work/1_backlog/{spike_id}.md"));
|
||||
assert!(spike_file.exists(), "expected spike file at {}", spike_file.display());
|
||||
let contents = std::fs::read_to_string(&spike_file).unwrap();
|
||||
assert!(contents.starts_with("---\nname: \"Compare Encoders\"\n---"));
|
||||
assert!(contents.contains("Which encoder is fastest?"));
|
||||
@@ -1087,12 +1092,14 @@ mod tests {
|
||||
let ctx = test_ctx(tmp.path());
|
||||
|
||||
let result = tool_create_spike(&json!({"name": "My Spike"}), &ctx).unwrap();
|
||||
assert!(result.contains("1_spike_my_spike"));
|
||||
assert!(result.contains("_spike_my_spike"), "result should contain spike ID: {result}");
|
||||
// Extract the actual spike ID from the result message (format: "Created spike: <id>").
|
||||
let spike_id = result.trim_start_matches("Created spike: ").trim();
|
||||
|
||||
let spike_file = tmp
|
||||
.path()
|
||||
.join(".huskies/work/1_backlog/1_spike_my_spike.md");
|
||||
assert!(spike_file.exists());
|
||||
.join(format!(".huskies/work/1_backlog/{spike_id}.md"));
|
||||
assert!(spike_file.exists(), "expected spike file at {}", spike_file.display());
|
||||
let contents = std::fs::read_to_string(&spike_file).unwrap();
|
||||
assert!(contents.starts_with("---\nname: \"My Spike\"\n---"));
|
||||
assert!(contents.contains("## Question\n\n- TBD\n"));
|
||||
|
||||
Reference in New Issue
Block a user