use serde::{Deserialize, Serialize};
use crate::response::Scope;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EntityRef {
pub id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
impl EntityRef {
pub fn new(id: impl Into<String>) -> Self {
Self {
id: id.into(),
label: None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EvidenceRef {
pub turn_id: String,
}
impl EvidenceRef {
pub fn new(turn_id: impl Into<String>) -> Self {
Self {
turn_id: turn_id.into(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Level {
Low,
Medium,
High,
}
impl Level {
pub fn rank(self) -> u8 {
match self {
Level::Low => 0,
Level::Medium => 1,
Level::High => 2,
}
}
}
pub type Criticality = Level;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Domain {
Ux,
Runtime,
Architecture,
Delivery,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum MitigationKind {
Prevention,
Detection,
FailFast,
}
impl MitigationKind {
pub fn rank(self) -> u8 {
match self {
MitigationKind::Prevention => 0,
MitigationKind::Detection => 1,
MitigationKind::FailFast => 2,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct FailureMode {
pub id: String,
pub session_id: String,
pub component: EntityRef,
pub description: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cause: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub effect: Option<String>,
#[serde(default)]
pub severity_observations: Vec<String>,
#[serde(default)]
pub probability_observations: Vec<String>,
pub domain: Domain,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub scope: Option<Scope>,
pub source: EvidenceRef,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Mitigation {
pub id: String,
pub session_id: String,
pub failure_mode_id: String,
pub kind: MitigationKind,
pub description: String,
#[serde(default)]
pub residual_severity_observations: Vec<String>,
#[serde(default)]
pub residual_probability_observations: Vec<String>,
pub source: EvidenceRef,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Rescore {
pub failure_mode_id: String,
pub session_id: String,
#[serde(default)]
pub severity_observations: Vec<String>,
#[serde(default)]
pub probability_observations: Vec<String>,
pub source: EvidenceRef,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum FailureModeStanding {
Unmitigated,
UnderMitigated,
Acceptable,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum IssueType {
UnmitigatedHigh,
UnmitigatedMedium,
MissingCause,
MissingEffect,
MissingScore,
WeakMitigationOrder,
ResidualStillHigh,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Issue {
pub id: String,
pub r#type: IssueType,
pub failure_mode_id: String,
pub severity: Level,
pub explanation: String,
pub suggested_action: String,
}