knowdit-repo-model 0.2.0

Smart contract auditing framework.
Documentation
use knowdit_kg_model::audit_finding::FindingSeverity;
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
use std::fmt;

/// Verdict produced by the Finding Reflector when reviewing a triggered violation.
#[derive(
    Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter, DeriveActiveEnum, Serialize, Deserialize,
)]
#[sea_orm(rs_type = "String", db_type = "String(StringLen::N(32))")]
pub enum ReflectionResult {
    /// The violation falls outside the project's auditing scope (e.g. excluded by README rules).
    #[sea_orm(string_value = "OutOfScope")]
    OutOfScope,
    /// The specification itself was incomplete or inaccurate; regenerate the spec.
    #[sea_orm(string_value = "IncompleteSpecification")]
    IncompleteSpecification,
    /// One of the call-sequence steps was incomplete; regenerate the harness.
    #[sea_orm(string_value = "IncompleteStep")]
    IncompleteStep,
    /// The violation matches the spec but is expected (e.g. `onlyOwner` revert).
    #[sea_orm(string_value = "ExpectedViolation")]
    ExpectedViolation,
    /// The violation is a real, in-scope vulnerability worth reporting.
    #[sea_orm(string_value = "ValidFinding")]
    ValidFinding,
}

impl ReflectionResult {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::OutOfScope => "OutOfScope",
            Self::IncompleteSpecification => "IncompleteSpecification",
            Self::IncompleteStep => "IncompleteStep",
            Self::ExpectedViolation => "ExpectedViolation",
            Self::ValidFinding => "ValidFinding",
        }
    }
}

impl fmt::Display for ReflectionResult {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.as_str())
    }
}

/// A reflection record explaining the verdict on a [`super::code_gen`] run.
///
/// `severity` is set only when `result == ValidFinding` so the reported
/// vulnerability can be ingested back into the historical knowledge graph.
#[sea_orm::model]
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, DeriveEntityModel)]
#[sea_orm(table_name = "reflection")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    #[sea_orm(indexed)]
    pub code_id: i32,
    #[sea_orm(indexed)]
    pub spec_id: i32,
    #[sea_orm(indexed)]
    pub result: ReflectionResult,
    #[sea_orm(column_type = "Text")]
    pub reason: String,
    #[sea_orm(nullable)]
    pub severity: Option<FindingSeverity>,

    #[sea_orm(belongs_to, from = "code_id", to = "id")]
    pub code_gen: HasOne<super::code_gen::Entity>,
    #[sea_orm(belongs_to, from = "spec_id", to = "id")]
    pub specification: HasOne<super::specification::Entity>,
}

impl ActiveModelBehavior for ActiveModel {}