use mj_core::review::driver::{Resolution, RoleState, RoleStatus, TurnReviewPhase};
use mj_core::review::lanes::ReviewTier;
use mj_core::review::verdict::ReviewVerdict;
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub struct RuntimeReviewView {
pub session_id: String,
pub tier: ReviewTier,
pub phase: TurnReviewPhase,
pub roles: Vec<RoleStatus>,
pub status: String,
pub verdict: Option<VerdictView>,
}
impl RuntimeReviewView {
#[must_use]
pub fn is_working(&self) -> bool {
matches!(
self.phase,
TurnReviewPhase::CapturingDelta
| TurnReviewPhase::LaunchingReviewer
| TurnReviewPhase::Running { .. }
| TurnReviewPhase::Forwarding { error: None, .. }
)
}
#[must_use]
pub fn activity_label(&self) -> Option<&'static str> {
match &self.phase {
TurnReviewPhase::Resolved(_) => None,
TurnReviewPhase::Forwarding { error: None, .. } => Some("Sending findings"),
TurnReviewPhase::Forwarding { error: Some(_), .. } => Some("Forward failed"),
TurnReviewPhase::Verdict(verdict) => Some(match verdict {
ReviewVerdict::Findings { .. } => "Findings",
ReviewVerdict::Failed { .. } => "Review failed",
ReviewVerdict::Clean => "Review complete",
}),
TurnReviewPhase::Running { roles }
if roles.iter().any(|role| {
role.role == mj_core::review::driver::VALIDATOR_ROLE
&& matches!(role.state, RoleState::Pending | RoleState::Running)
}) =>
{
Some("Validating")
}
_ => Some("Reviewing"),
}
}
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub struct VerdictView {
pub kind: VerdictKind,
pub text: String,
pub allowed: Vec<Resolution>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum VerdictKind {
Clean,
Findings,
Failed,
}
#[must_use]
pub fn role_session_id(primary_session_id: &str, role: &str) -> String {
if role == mj_core::review::driver::REVIEWER_ROLE {
format!("{primary_session_id}-reviewer")
} else {
format!("{primary_session_id}-review-{role}")
}
}