use std::collections::HashMap; use shared_kernel::normalize_required_string; use crate::{AiTaskFieldError, AiTaskStageKind}; use super::inputs::AiTaskCreateInput; pub fn validate_task_create_input(input: &AiTaskCreateInput) -> Result<(), AiTaskFieldError> { if normalize_required_string(&input.task_id).is_none() { return Err(AiTaskFieldError::MissingTaskId); } if normalize_required_string(&input.owner_user_id).is_none() { return Err(AiTaskFieldError::MissingOwnerUserId); } if normalize_required_string(&input.request_label).is_none() { return Err(AiTaskFieldError::MissingRequestLabel); } if normalize_required_string(&input.source_module).is_none() { return Err(AiTaskFieldError::MissingSourceModule); } if input.stages.is_empty() { return Err(AiTaskFieldError::MissingStageBlueprints); } let mut seen: HashMap = HashMap::new(); for stage in &input.stages { if normalize_required_string(&stage.label).is_none() || normalize_required_string(&stage.detail).is_none() { return Err(AiTaskFieldError::MissingStageBlueprints); } if seen.insert(stage.stage_kind, true).is_some() { return Err(AiTaskFieldError::DuplicateStageBlueprint); } } Ok(()) }