aboutsummaryrefslogtreecommitdiff
path: root/src/models.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/models.rs')
-rw-r--r--src/models.rs274
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.
+}