Skip to main content

perfgate_server/
models.rs

1//! Data models for the perfgate baseline service.
2//!
3//! These types represent the core domain objects and API request/response types
4//! for the baseline storage service.
5
6use chrono::Utc;
7pub use perfgate_api::*;
8use sha2::{Digest, Sha256};
9use std::collections::BTreeMap;
10
11/// Extends BaselineRecord with server-side logic.
12pub trait BaselineRecordExt {
13    #[allow(clippy::new_ret_no_self, clippy::too_many_arguments)]
14    fn new(
15        project: String,
16        benchmark: String,
17        version: String,
18        receipt: perfgate_types::RunReceipt,
19        git_ref: Option<String>,
20        git_sha: Option<String>,
21        metadata: BTreeMap<String, String>,
22        tags: Vec<String>,
23        source: BaselineSource,
24    ) -> BaselineRecord;
25}
26
27impl BaselineRecordExt for BaselineRecord {
28    fn new(
29        project: String,
30        benchmark: String,
31        version: String,
32        receipt: perfgate_types::RunReceipt,
33        git_ref: Option<String>,
34        git_sha: Option<String>,
35        metadata: BTreeMap<String, String>,
36        tags: Vec<String>,
37        source: BaselineSource,
38    ) -> Self {
39        let now = Utc::now();
40        let id = generate_ulid();
41        let content_hash = compute_content_hash(&receipt);
42
43        Self {
44            schema: BASELINE_SCHEMA_V1.to_string(),
45            id,
46            project,
47            benchmark,
48            version,
49            git_ref,
50            git_sha,
51            receipt,
52            metadata,
53            tags,
54            created_at: now,
55            updated_at: now,
56            content_hash,
57            source,
58            deleted: false,
59        }
60    }
61}
62
63/// Computes a content hash for a run receipt.
64pub fn compute_content_hash(receipt: &perfgate_types::RunReceipt) -> String {
65    let mut hasher = Sha256::new();
66    let json = serde_json::to_string(receipt).unwrap_or_default();
67    hasher.update(json.as_bytes());
68    format!("{:x}", hasher.finalize())
69}
70
71/// Generates a new unique identifier (ULID-like format).
72pub fn generate_ulid() -> String {
73    uuid::Uuid::new_v4().simple().to_string()
74}