use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Action {
pub id: String,
pub priority: u8,
pub effort: u8,
pub impact: u32,
pub quick_win: bool,
pub title: String,
pub evidence: String,
}
impl Action {
pub fn new(id: &str, priority: u8, effort: u8, title: &str, evidence: String) -> Self {
let impact = ((4 - priority.min(3)) as u32)
.saturating_mul(30)
.saturating_sub((effort.saturating_sub(1)) as u32 * 5);
Self {
id: id.to_string(),
priority,
effort,
impact,
quick_win: impact >= 55 && effort == 1,
title: title.to_string(),
evidence,
}
}
}
pub fn grade(score: u32) -> &'static str {
if score >= 90 {
"A"
} else if score >= 75 {
"B"
} else if score >= 60 {
"C"
} else if score >= 40 {
"D"
} else {
"F"
}
}
pub fn rank(mut actions: Vec<Action>) -> Vec<Action> {
actions.sort_by(|a, b| {
b.impact
.cmp(&a.impact)
.then(a.effort.cmp(&b.effort))
.then(a.id.cmp(&b.id))
});
actions
}
pub fn top(actions: &[Action], n: usize) -> &[Action] {
&actions[..actions.len().min(n)]
}