use serde::{Serialize, Deserialize};
use crate::analyzer::SchemaChange;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MigrationPlan {
pub source_version: String,
pub target_version: String,
pub changes: Vec<SchemaChange>,
pub impact_score: u8,
pub is_breaking: bool,
}
impl MigrationPlan {
pub fn new(source_version: String, target_version: String, changes: Vec<SchemaChange>) -> Self {
let impact_score = Self::calculate_impact(&changes);
let is_breaking = Self::detect_breaking_changes(&changes);
Self {
source_version,
target_version,
changes,
impact_score,
is_breaking,
}
}
fn calculate_impact(changes: &[SchemaChange]) -> u8 {
let score = changes.iter().map(|change| match change.change_type {
crate::analyzer::ChangeType::Addition => 25,
crate::analyzer::ChangeType::Removal => 100,
crate::analyzer::ChangeType::Modification => 50,
crate::analyzer::ChangeType::Rename => 30,
}).max().unwrap_or(0);
score.min(100) as u8
}
fn detect_breaking_changes(changes: &[SchemaChange]) -> bool {
changes.iter().any(|change| matches!(
change.change_type,
crate::analyzer::ChangeType::Removal | crate::analyzer::ChangeType::Modification
))
}
pub fn breaking_changes(&self) -> Vec<&SchemaChange> {
self.changes.iter()
.filter(|change| matches!(
change.change_type,
crate::analyzer::ChangeType::Removal | crate::analyzer::ChangeType::Modification
))
.collect()
}
}