use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use crate::core::backends::ResourceLocator;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpecContentData {
pub spec: String,
pub notes: String,
pub tasks: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Spec {
pub name: String,
pub created_at: String,
pub path: PathBuf, pub project_name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub location_hint: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub locator: Option<ResourceLocator>,
pub content: SpecContentData,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpecConfig {
pub project_name: String,
pub feature_name: String,
pub content: SpecContentData,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpecMetadata {
pub name: String,
pub created_at: String,
pub feature_name: String,
pub project_name: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SpecFilter {
pub feature_name_contains: Option<String>,
pub created_after: Option<String>,
pub created_before: Option<String>,
pub limit: Option<usize>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum SpecFileType {
Spec,
Notes,
TaskList,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContentValidationStatus {
pub spec_valid: bool,
pub notes_valid: bool,
pub task_list_valid: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpecValidationResult {
pub spec_name: String,
pub project_name: String,
pub spec_file_exists: bool,
pub notes_file_exists: bool,
pub task_list_file_exists: bool,
pub content_validation: ContentValidationStatus,
pub validation_errors: Vec<String>,
}
impl SpecValidationResult {
pub fn is_valid(&self) -> bool {
self.spec_file_exists
&& self.notes_file_exists
&& self.task_list_file_exists
&& self.content_validation.spec_valid
&& self.content_validation.notes_valid
&& self.content_validation.task_list_valid
&& self.validation_errors.is_empty()
}
pub fn summary(&self) -> String {
if self.is_valid() {
"Spec is valid".to_string()
} else {
format!(
"Spec validation failed: {} errors",
self.validation_errors.len()
)
}
}
}