Skip to main content

meritocrab_db/
models.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use sqlx::FromRow;
4
5/// Contributor database model
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Contributor {
8    pub id: i64,
9    pub github_user_id: i64,
10    pub repo_owner: String,
11    pub repo_name: String,
12    pub credit_score: i32,
13    pub role: Option<String>,
14    pub is_blacklisted: bool,
15    pub created_at: DateTime<Utc>,
16    pub updated_at: DateTime<Utc>,
17}
18
19/// Raw contributor model from database (with string timestamps)
20#[derive(Debug, Clone, FromRow)]
21pub(crate) struct ContributorRaw {
22    pub id: i64,
23    pub github_user_id: i64,
24    pub repo_owner: String,
25    pub repo_name: String,
26    pub credit_score: i32,
27    pub role: Option<String>,
28    pub is_blacklisted: i32, // SQLite BOOLEAN as INTEGER
29    pub created_at: String,
30    pub updated_at: String,
31}
32
33impl From<ContributorRaw> for Contributor {
34    fn from(raw: ContributorRaw) -> Self {
35        Self {
36            id: raw.id,
37            github_user_id: raw.github_user_id,
38            repo_owner: raw.repo_owner,
39            repo_name: raw.repo_name,
40            credit_score: raw.credit_score,
41            role: raw.role,
42            is_blacklisted: raw.is_blacklisted != 0,
43            created_at: DateTime::parse_from_rfc3339(&raw.created_at)
44                .unwrap()
45                .with_timezone(&Utc),
46            updated_at: DateTime::parse_from_rfc3339(&raw.updated_at)
47                .unwrap()
48                .with_timezone(&Utc),
49        }
50    }
51}
52
53/// Credit event database model (immutable audit log)
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct CreditEvent {
56    pub id: i64,
57    pub contributor_id: i64,
58    pub event_type: String,
59    pub delta: i32,
60    pub credit_before: i32,
61    pub credit_after: i32,
62    pub llm_evaluation: Option<String>,
63    pub maintainer_override: Option<String>,
64    pub created_at: DateTime<Utc>,
65}
66
67/// Raw credit event model from database (with string timestamp)
68#[derive(Debug, Clone, FromRow)]
69pub(crate) struct CreditEventRaw {
70    pub id: i64,
71    pub contributor_id: i64,
72    pub event_type: String,
73    pub delta: i32,
74    pub credit_before: i32,
75    pub credit_after: i32,
76    pub llm_evaluation: Option<String>,
77    pub maintainer_override: Option<String>,
78    pub created_at: String,
79}
80
81impl From<CreditEventRaw> for CreditEvent {
82    fn from(raw: CreditEventRaw) -> Self {
83        Self {
84            id: raw.id,
85            contributor_id: raw.contributor_id,
86            event_type: raw.event_type,
87            delta: raw.delta,
88            credit_before: raw.credit_before,
89            credit_after: raw.credit_after,
90            llm_evaluation: raw.llm_evaluation,
91            maintainer_override: raw.maintainer_override,
92            created_at: DateTime::parse_from_rfc3339(&raw.created_at)
93                .unwrap()
94                .with_timezone(&Utc),
95        }
96    }
97}
98
99/// Pending evaluation database model
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct PendingEvaluation {
102    pub id: String,
103    pub contributor_id: i64,
104    pub repo_owner: String,
105    pub repo_name: String,
106    pub llm_classification: String,
107    pub confidence: f64,
108    pub proposed_delta: i32,
109    pub status: String,
110    pub maintainer_note: Option<String>,
111    pub final_delta: Option<i32>,
112    pub created_at: DateTime<Utc>,
113    pub updated_at: DateTime<Utc>,
114}
115
116/// Raw pending evaluation model from database (with string timestamps)
117#[derive(Debug, Clone, FromRow)]
118pub(crate) struct PendingEvaluationRaw {
119    pub id: String,
120    pub contributor_id: i64,
121    pub repo_owner: String,
122    pub repo_name: String,
123    pub llm_classification: String,
124    pub confidence: f64,
125    pub proposed_delta: i32,
126    pub status: String,
127    pub maintainer_note: Option<String>,
128    pub final_delta: Option<i32>,
129    pub created_at: String,
130    pub updated_at: String,
131}
132
133impl From<PendingEvaluationRaw> for PendingEvaluation {
134    fn from(raw: PendingEvaluationRaw) -> Self {
135        Self {
136            id: raw.id,
137            contributor_id: raw.contributor_id,
138            repo_owner: raw.repo_owner,
139            repo_name: raw.repo_name,
140            llm_classification: raw.llm_classification,
141            confidence: raw.confidence,
142            proposed_delta: raw.proposed_delta,
143            status: raw.status,
144            maintainer_note: raw.maintainer_note,
145            final_delta: raw.final_delta,
146            created_at: DateTime::parse_from_rfc3339(&raw.created_at)
147                .unwrap()
148                .with_timezone(&Utc),
149            updated_at: DateTime::parse_from_rfc3339(&raw.updated_at)
150                .unwrap()
151                .with_timezone(&Utc),
152        }
153    }
154}
155
156/// Repo config database model
157#[derive(Debug, Clone, Serialize, Deserialize)]
158pub struct RepoConfig {
159    pub id: i64,
160    pub owner: String,
161    pub repo: String,
162    pub config_json: String,
163    pub cached_at: DateTime<Utc>,
164    pub ttl: i64,
165}
166
167/// Raw repo config model from database (with string timestamp)
168#[derive(Debug, Clone, FromRow)]
169pub(crate) struct RepoConfigRaw {
170    pub id: i64,
171    pub owner: String,
172    pub repo: String,
173    pub config_json: String,
174    pub cached_at: String,
175    pub ttl: i64,
176}
177
178impl From<RepoConfigRaw> for RepoConfig {
179    fn from(raw: RepoConfigRaw) -> Self {
180        Self {
181            id: raw.id,
182            owner: raw.owner,
183            repo: raw.repo,
184            config_json: raw.config_json,
185            cached_at: DateTime::parse_from_rfc3339(&raw.cached_at)
186                .unwrap()
187                .with_timezone(&Utc),
188            ttl: raw.ttl,
189        }
190    }
191}