refactor: split http/workflow/story_ops.rs (1256) into create + criterion + update

The 1256-line story_ops.rs is split:

- create.rs: create_story_file + tests (~232 lines)
- criterion.rs: check/add/remove/edit_criterion_in_file + tests (~525 lines)
- update.rs: update_story_in_file + yaml helpers + tests (~640 lines)
- mod.rs: re-exports (~12 lines)

Workflow helpers (read_story_content, write_story_content, slugify_name, etc.)
bumped from pub(super) to pub(crate) since they're now consumed across nested
sub-modules and from http/mcp/story_tools/.

Tests stay co-located. All 2636 tests pass; clippy clean.
This commit is contained in:
dave
2026-04-27 02:13:31 +00:00
parent 34a399b838
commit adf936be07
6 changed files with 1399 additions and 1263 deletions
+7 -7
View File
@@ -300,13 +300,13 @@ pub fn validate_story_dirs(_root: &std::path::Path) -> Result<Vec<StoryValidatio
/// Read story content from the database content store.
///
/// Returns the story content or an error if not found.
pub(super) fn read_story_content(_project_root: &Path, story_id: &str) -> Result<String, String> {
pub(crate) fn read_story_content(_project_root: &Path, story_id: &str) -> Result<String, String> {
crate::db::read_content(story_id)
.ok_or_else(|| format!("Story '{story_id}' not found in any pipeline stage."))
}
/// Write story content to the DB content store and CRDT.
pub(super) fn write_story_content(
pub(crate) fn write_story_content(
_project_root: &Path,
story_id: &str,
stage: &str,
@@ -316,7 +316,7 @@ pub(super) fn write_story_content(
}
/// Determine what stage a story is in (from CRDT).
pub(super) fn story_stage(story_id: &str) -> Option<String> {
pub(crate) fn story_stage(story_id: &str) -> Option<String> {
crate::pipeline_state::read_typed(story_id)
.ok()
.flatten()
@@ -328,7 +328,7 @@ pub(super) fn story_stage(story_id: &str) -> Option<String> {
/// Finds the first occurrence of `## {section_name}` and replaces everything
/// until the next `##` heading (or end of file) with the provided text.
/// Returns an error if the section is not found.
pub(super) fn replace_section_content(
pub(crate) fn replace_section_content(
content: &str,
section_name: &str,
new_text: &str,
@@ -381,7 +381,7 @@ pub(super) fn replace_section_content(
/// The new section is placed immediately before the first occurrence of
/// `## {before_section}`. If `before_section` is `None` or not found in the
/// document, the section is appended at the end.
pub(super) fn create_section_content(
pub(crate) fn create_section_content(
content: &str,
section_name: &str,
new_text: &str,
@@ -468,7 +468,7 @@ pub(super) fn replace_or_append_section(contents: &str, header: &str, new_sectio
}
}
pub(super) fn slugify_name(name: &str) -> String {
pub(crate) fn slugify_name(name: &str) -> String {
let slug: String = name
.chars()
.map(|c| {
@@ -501,7 +501,7 @@ pub(super) fn slugify_name(name: &str) -> String {
}
/// Get the next available item number from the database/CRDT.
pub(super) fn next_item_number(_root: &std::path::Path) -> Result<u32, String> {
pub(crate) fn next_item_number(_root: &std::path::Path) -> Result<u32, String> {
Ok(crate::db::next_item_number())
}