diff options
| author | UMTS at Teleco <crt@teleco.ch> | 2025-12-13 02:51:15 +0100 |
|---|---|---|
| committer | UMTS at Teleco <crt@teleco.ch> | 2025-12-13 02:51:15 +0100 |
| commit | 8323fdd73272a2882781aba3c499ba0be3dff2a6 (patch) | |
| tree | ffbf86473933e69cfaeef30d5c6ea7e5b494856c /src/models.rs | |
Diffstat (limited to 'src/models.rs')
| -rw-r--r-- | src/models.rs | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/src/models.rs b/src/models.rs new file mode 100644 index 0000000..87ef410 --- /dev/null +++ b/src/models.rs @@ -0,0 +1,274 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +// ============================================================================ +// API Response Types +// ============================================================================ + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ApiResponse<T> { + pub success: bool, + pub data: Option<T>, + pub error: Option<String>, + pub message: Option<String>, +} + +/// Format backend error payloads into a readable string. +pub fn api_error_detail(error: &Option<String>) -> String { + error + .as_ref() + .map(String::from) + .unwrap_or_else(|| "Unknown backend error".to_string()) +} + +// ============================================================================ +// Authentication +// ============================================================================ + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct LoginRequest { + pub method: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub username: Option<String>, + #[serde(skip_serializing_if = "Option::is_none")] + pub password: Option<String>, + #[serde(skip_serializing_if = "Option::is_none")] + pub pin: Option<String>, + #[serde(skip_serializing_if = "Option::is_none")] + pub login_string: Option<String>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct LoginResponse { + pub success: bool, + pub token: String, + pub user: UserInfo, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct UserInfo { + pub id: i32, + pub username: String, + pub role: String, + pub power: i32, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SessionStatus { + pub valid: bool, + pub user: Option<UserInfo>, + pub expires_at: Option<DateTime<Utc>>, + pub message: Option<String>, +} + +// ============================================================================ +// Permissions +// ============================================================================ + +#[allow(dead_code)] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PermissionsResponse { + pub user: UserInfo, + pub user_settings_access: String, + pub permissions: serde_json::Value, // Flexible permissions structure + pub security_clearance: Option<String>, +} + +// ============================================================================ +// Preferences +// ============================================================================ + +#[allow(dead_code)] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PreferencesRequest { + pub action: String, // "get", "set", "reset" + #[serde(skip_serializing_if = "Option::is_none")] + pub user_id: Option<i32>, + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "preferences")] + pub preferences: Option<serde_json::Value>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PreferencesResponse { + pub user_id: i32, + pub preferences: serde_json::Value, +} + +// ============================================================================ +// Query Operations +// ============================================================================ + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct QueryRequest { + pub action: String, // "select", "insert", "update", "delete", "count" + pub table: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub columns: Option<Vec<String>>, + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "data")] + pub data: Option<serde_json::Value>, + #[serde(skip_serializing_if = "Option::is_none")] + pub r#where: Option<serde_json::Value>, + #[serde(skip_serializing_if = "Option::is_none")] + pub filter: Option<serde_json::Value>, + #[serde(skip_serializing_if = "Option::is_none")] + pub order_by: Option<Vec<OrderBy>>, + #[serde(skip_serializing_if = "Option::is_none")] + pub limit: Option<u32>, + #[serde(skip_serializing_if = "Option::is_none")] + pub offset: Option<u32>, + #[serde(skip_serializing_if = "Option::is_none")] + pub joins: Option<Vec<Join>>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct OrderBy { + pub column: String, + pub direction: String, // "ASC" or "DESC" +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Join { + pub table: String, + pub on: String, + #[serde(rename = "type")] + pub join_type: String, // "INNER", "LEFT", "RIGHT" - serialized as "type" for API +} + +// ============================================================================ +// Asset Models +// ============================================================================ + +#[allow(dead_code)] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Asset { + pub id: Option<i32>, + pub asset_tag: String, + pub asset_numeric_id: Option<i32>, + pub asset_type: String, // "N", "T", "C" + pub name: String, + pub description: Option<String>, + pub category_id: Option<i32>, + pub zone_id: Option<i32>, + pub zone_plus: Option<String>, // "Exact", "Clarify", "Deployed" + pub zone_note: Option<String>, + pub manufacturer: Option<String>, + pub model: Option<String>, + pub serial_number: Option<String>, + pub status: String, // "Good", "Faulty", "Scrapped", "Missing" + pub price: Option<f64>, + pub purchase_date: Option<String>, + pub warranty_expiry: Option<String>, + pub supplier_id: Option<i32>, + pub lendable: bool, + pub lending_status: Option<String>, // "Available", "Borrowed", "Deployed", "Overdue" + pub asset_image: Option<String>, + pub notes: Option<String>, + pub created_by: Option<i32>, + pub created_date: Option<DateTime<Utc>>, + pub last_modified_by: Option<i32>, + pub last_modified_date: Option<DateTime<Utc>>, +} + +// ============================================================================ +// Borrower Models +// ============================================================================ + +#[allow(dead_code)] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Borrower { + pub id: Option<i32>, + pub borrower_code: String, + pub name: String, + pub email: Option<String>, + pub phone: Option<String>, + pub borrower_type: String, // "Student", "Faculty", "Staff", "External" + pub department: Option<String>, + pub banned: bool, + pub unban_fine: Option<f64>, + pub ban_reason: Option<String>, + pub notes: Option<String>, +} + +// ============================================================================ +// Category & Zone Models +// ============================================================================ + +#[allow(dead_code)] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Category { + pub id: Option<i32>, + pub category_code: String, + pub name: String, + pub description: Option<String>, +} + +#[allow(dead_code)] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Zone { + pub id: Option<i32>, + pub zone_code: String, + pub name: String, + pub parent_zone_id: Option<i32>, + pub level: i32, + pub description: Option<String>, +} + +// ============================================================================ +// Lending History +// ============================================================================ + +#[allow(dead_code)] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct LendingHistory { + pub id: Option<i32>, + pub asset_id: i32, + pub borrower_id: i32, + pub checkout_date: DateTime<Utc>, + pub due_date: String, + pub return_date: Option<DateTime<Utc>>, + pub status: String, // "Active", "Returned", "Overdue", "Lost" + pub checkout_condition: Option<String>, + pub return_condition: Option<String>, + pub notes: Option<String>, + pub checked_out_by: Option<i32>, + pub checked_in_by: Option<i32>, +} + +// ============================================================================ +// Issue Tracker +// ============================================================================ + +#[allow(dead_code)] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Issue { + pub id: Option<i32>, + pub issue_type: String, // "Asset Issue", "Borrower Issue", "System Issue" + pub asset_id: Option<i32>, + pub borrower_id: Option<i32>, + pub title: String, + pub description: Option<String>, + pub severity: String, // "Low", "Medium", "High", "Critical" + pub priority: String, // "Low", "Medium", "High", "Critical" + pub status: String, // "Open", "In Progress", "On Hold", "Resolved", "Closed" + pub solution: Option<String>, + pub solution_plus: Option<String>, + pub auto_detected: bool, + pub detection_trigger: Option<String>, + pub reported_by: Option<i32>, + pub reported_date: Option<DateTime<Utc>>, + pub resolved_by: Option<i32>, + pub resolved_date: Option<DateTime<Utc>>, +} + +// ============================================================================ +// Dashboard Stats +// ============================================================================ + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct DashboardStats { + pub total_assets: i32, + pub okay_items: i32, // All items with status "Good" + pub attention_items: i32, // Faulty, Missing, Overdue, Attention, etc. +} |
