huskies: merge 492_story_remove_filesystem_pipeline_state_and_store_story_content_in_database
This commit is contained in:
@@ -402,10 +402,15 @@ pub async fn handle_timer_command(
|
||||
|
||||
// The story must be in backlog or current. When the timer fires,
|
||||
// backlog stories are moved to current automatically.
|
||||
let work_dir = project_root.join(".huskies").join("work");
|
||||
let in_backlog = work_dir.join("1_backlog").join(format!("{story_id}.md")).exists();
|
||||
let in_current = work_dir.join("2_current").join(format!("{story_id}.md")).exists();
|
||||
if !in_backlog && !in_current {
|
||||
// Check CRDT state first, then fall back to filesystem.
|
||||
let in_valid_stage = if let Some(item) = crate::crdt_state::read_item(&story_id) {
|
||||
matches!(item.stage.as_str(), "1_backlog" | "2_current")
|
||||
} else {
|
||||
let work_dir = project_root.join(".huskies").join("work");
|
||||
work_dir.join("1_backlog").join(format!("{story_id}.md")).exists()
|
||||
|| work_dir.join("2_current").join(format!("{story_id}.md")).exists()
|
||||
};
|
||||
if !in_valid_stage {
|
||||
return format!(
|
||||
"Story **{story_id}** is not in backlog or current."
|
||||
);
|
||||
@@ -558,6 +563,15 @@ fn resolve_story_id(number_or_id: &str, project_root: &Path) -> Option<String> {
|
||||
return None;
|
||||
}
|
||||
|
||||
// --- DB-first lookup ---
|
||||
for id in crate::db::all_content_ids() {
|
||||
let file_num = id.split('_').next().unwrap_or("");
|
||||
if file_num == number_or_id && crate::crdt_state::read_item(&id).is_some() {
|
||||
return Some(id);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Filesystem fallback ---
|
||||
for stage in STAGES {
|
||||
let dir = project_root.join(".huskies").join("work").join(stage);
|
||||
if !dir.exists() {
|
||||
@@ -1111,15 +1125,19 @@ mod tests {
|
||||
let current = root.join(".huskies/work/2_current");
|
||||
fs::create_dir_all(&backlog).unwrap();
|
||||
fs::create_dir_all(¤t).unwrap();
|
||||
// Use a unique high-numbered story ID (9905) that is unlikely to be in
|
||||
// the global content store from a parallel test. Write ONLY to the
|
||||
// filesystem so that move_story_to_current uses the filesystem path,
|
||||
// which actually moves the file on disk.
|
||||
fs::write(
|
||||
backlog.join("421_story_foo.md"),
|
||||
backlog.join("9905_story_foo.md"),
|
||||
"---\nname: Foo\n---\n",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let store = Arc::new(TimerStore::load(root.join("timers.json")));
|
||||
let past = Utc::now() - Duration::seconds(5);
|
||||
store.add("421_story_foo".to_string(), past).unwrap();
|
||||
store.add("9905_story_foo".to_string(), past).unwrap();
|
||||
assert_eq!(store.list().len(), 1, "precondition: one pending timer");
|
||||
|
||||
let agents = Arc::new(crate::agents::AgentPool::new_test(19999));
|
||||
@@ -1134,7 +1152,7 @@ mod tests {
|
||||
);
|
||||
// Story should have been moved to current.
|
||||
assert!(
|
||||
current.join("421_story_foo.md").exists(),
|
||||
current.join("9905_story_foo.md").exists(),
|
||||
"story should be in 2_current/ after tick fires"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user