huskies: merge 1141 story Convert work-item type between spike/story/bug/refactor (or at least spike→story)
This commit is contained in:
@@ -22,7 +22,8 @@ pub use newtypes::{
|
||||
AcceptanceCriterion, DependsOnId, Description, StoryId, StoryName, TargetStage,
|
||||
};
|
||||
pub use requests::{
|
||||
AddCriterionRequest, CreateBugRequest, CreateEpicRequest, CreateRefactorRequest,
|
||||
CreateSpikeRequest, CreateStoryRequest, EditCriterionRequest, FreezeStoryRequest,
|
||||
MoveStoryRequest, MoveStoryToMergeRequest, UnblockStoryRequest, UpdateStoryRequest,
|
||||
AddCriterionRequest, ConvertItemTypeRequest, CreateBugRequest, CreateEpicRequest,
|
||||
CreateRefactorRequest, CreateSpikeRequest, CreateStoryRequest, EditCriterionRequest,
|
||||
FreezeStoryRequest, MoveStoryRequest, MoveStoryToMergeRequest, UnblockStoryRequest,
|
||||
UpdateStoryRequest,
|
||||
};
|
||||
|
||||
@@ -1212,6 +1212,81 @@ impl FreezeStoryRequest {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ConvertItemTypeRequest
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Fully validated inputs for the `convert_item_type` MCP tool and `convert` chat command.
|
||||
#[derive(Debug)]
|
||||
pub struct ConvertItemTypeRequest {
|
||||
/// Validated story identifier.
|
||||
pub story_id: StoryId,
|
||||
/// The target item type.
|
||||
pub new_type: crate::io::story_metadata::ItemType,
|
||||
}
|
||||
|
||||
impl ConvertItemTypeRequest {
|
||||
/// Parse and validate a `convert_item_type` JSON argument map.
|
||||
///
|
||||
/// Required fields: `story_id` (work-item filename stem), `new_type`
|
||||
/// (one of `"story"`, `"bug"`, `"spike"`, `"refactor"`, `"epic"`).
|
||||
pub fn from_json(args: &serde_json::Value) -> Result<Self, String> {
|
||||
let mut errors: Vec<ValidationError> = Vec::new();
|
||||
|
||||
let story_id = match args.get("story_id").and_then(|v| v.as_str()) {
|
||||
None => {
|
||||
errors.push(ValidationError::FieldMissing {
|
||||
field: "story_id".into(),
|
||||
});
|
||||
None
|
||||
}
|
||||
Some(raw) => match StoryId::parse(raw) {
|
||||
Ok(id) => Some(id),
|
||||
Err(mut errs) => {
|
||||
errors.append(&mut errs);
|
||||
None
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let new_type = match args.get("new_type").and_then(|v| v.as_str()) {
|
||||
None => {
|
||||
errors.push(ValidationError::FieldMissing {
|
||||
field: "new_type".into(),
|
||||
});
|
||||
None
|
||||
}
|
||||
Some(raw) => match crate::io::story_metadata::ItemType::from_str(raw) {
|
||||
Some(t) => Some(t),
|
||||
None => {
|
||||
errors.push(ValidationError::InvalidValue {
|
||||
field: "new_type".into(),
|
||||
actual: raw.to_string(),
|
||||
allowed: vec![
|
||||
"story".into(),
|
||||
"bug".into(),
|
||||
"spike".into(),
|
||||
"refactor".into(),
|
||||
"epic".into(),
|
||||
],
|
||||
});
|
||||
None
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if !errors.is_empty() {
|
||||
return Err(format_errors_as_json(&errors));
|
||||
}
|
||||
|
||||
Ok(ConvertItemTypeRequest {
|
||||
story_id: story_id.unwrap(),
|
||||
new_type: new_type.unwrap(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user