db/models/
plagiarism_case.rs

1//! Entity and business logic for managing plagiarism cases.
2//!
3//! This module defines the `PlagiarismCase` model and methods to create
4//! and relate plagiarism reports to assignment submissions.
5
6use chrono::{DateTime, Utc};
7use sea_orm::entity::prelude::*;
8use sea_orm::{ActiveValue::Set, DatabaseConnection, EntityTrait, DbErr};
9
10/// Represents a detected plagiarism case between two submissions.
11#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
12#[sea_orm(table_name = "plagiarism_cases")]
13pub struct Model {
14    /// Primary key for the plagiarism case.
15    #[sea_orm(primary_key)]
16    pub id: i64,
17
18    /// ID of the assignment this case belongs to.
19    pub assignment_id: i64,
20
21    /// ID of the first submission involved in the case.
22    pub submission_id_1: i64,
23
24    /// ID of the second submission involved in the case.
25    pub submission_id_2: i64,
26
27    /// Description of the plagiarism incident.
28    pub description: String,
29
30    /// The review status of the case.
31    pub status: Status,
32
33    /// Similarity percentage (0–100) as float
34    pub similarity: f32,
35
36    /// Timestamp when the case was created.
37    pub created_at: DateTime<Utc>,
38
39    /// Timestamp when the case was last updated.
40    pub updated_at: DateTime<Utc>,
41}
42
43/// Defines the possible review statuses for a plagiarism case.
44#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, sea_orm::strum::Display, sea_orm::strum::EnumString)]
45#[sea_orm(rs_type = "String", db_type = "Text")]
46#[strum(serialize_all = "lowercase", ascii_case_insensitive)]
47pub enum Status {
48    /// The case has not yet been reviewed.
49    #[sea_orm(string_value = "review")]
50    Review,
51    /// The case has been flagged for potential plagiarism.
52    #[sea_orm(string_value = "flagged")]
53    Flagged,
54    /// The case has been reviewed and cleared.
55    #[sea_orm(string_value = "reviewed")]
56    Reviewed,
57}
58
59/// Defines relationships to assignment submissions.
60#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
61pub enum Relation {
62    #[sea_orm(
63        belongs_to = "super::assignment_submission::Entity",
64        from = "Column::SubmissionId1",
65        to = "super::assignment_submission::Column::Id"
66    )]
67    Submission1,
68
69    #[sea_orm(
70        belongs_to = "super::assignment_submission::Entity",
71        from = "Column::SubmissionId2",
72        to = "super::assignment_submission::Column::Id"
73    )]
74    Submission2,
75}
76
77impl ActiveModelBehavior for ActiveModel {}
78
79impl Model {
80    /// Creates a new plagiarism case entry in the database.
81    ///
82    /// # Arguments
83    /// - `db`: The active database connection.
84    /// - `submission_id_1`: ID of the first submission involved.
85    /// - `submission_id_2`: ID of the second submission involved.
86    /// - `description`: Human-readable explanation of the case.
87    ///
88    /// # Returns
89    /// - `Ok(Self)` on success with the inserted model.
90    /// - `Err(DbErr)` if the insert fails.
91    pub async fn create_case(
92        db: &DatabaseConnection,
93        assignment_id: i64,
94        submission_id_1: i64,
95        submission_id_2: i64,
96        description: &str,
97        similarity: f32, 
98    ) -> Result<Self, DbErr> {
99        let now = Utc::now();
100        let active = ActiveModel {
101            assignment_id: Set(assignment_id),
102            submission_id_1: Set(submission_id_1),
103            submission_id_2: Set(submission_id_2),
104            description: Set(description.to_string()),
105            status: Set(Status::Review),
106            similarity: Set(similarity),
107            created_at: Set(now),
108            updated_at: Set(now),
109            ..Default::default()
110        };
111        active.insert(db).await
112    }
113}