// Core domain models for VAPORA v1.0 // Phase 1: Complete type definitions for backend use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; // ============================================================================ // Project Models // ============================================================================ /// Project model #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Project { #[serde(skip_serializing_if = "Option::is_none")] pub id: Option, pub tenant_id: String, pub title: String, pub description: Option, pub status: ProjectStatus, #[serde(default)] pub features: Vec, pub created_at: DateTime, pub updated_at: DateTime, } /// Project status enumeration #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum ProjectStatus { Active, Archived, Completed, } // ============================================================================ // Task Models // ============================================================================ /// Task model for Kanban board #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Task { #[serde(skip_serializing_if = "Option::is_none")] pub id: Option, pub tenant_id: String, pub project_id: String, pub title: String, pub description: Option, pub status: TaskStatus, pub assignee: String, pub priority: TaskPriority, pub task_order: i32, pub feature: Option, pub created_at: DateTime, pub updated_at: DateTime, } /// Task status for Kanban columns #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum TaskStatus { Todo, Doing, Review, Done, } /// Task priority levels #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(rename_all = "lowercase")] pub enum TaskPriority { Low, Medium, High, Critical, } // ============================================================================ // Agent Models // ============================================================================ /// Agent registry model (12 specialized roles) #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Agent { pub id: String, pub role: AgentRole, pub name: String, pub version: String, pub status: AgentStatus, #[serde(default)] pub capabilities: Vec, #[serde(default)] pub skills: Vec, pub llm_provider: String, pub llm_model: String, pub max_concurrent_tasks: u32, pub created_at: DateTime, } /// Agent role enumeration (12 roles as per VAPORA spec) #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum AgentRole { Architect, Developer, CodeReviewer, Tester, Documenter, Marketer, Presenter, DevOps, Monitor, Security, ProjectManager, DecisionMaker, } /// Agent status #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum AgentStatus { Active, Inactive, Updating, Error, } /// Agent instance (runtime pod) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AgentInstance { #[serde(skip_serializing_if = "Option::is_none")] pub id: Option, pub agent_id: String, pub pod_id: String, pub ip: Option, pub port: u16, pub start_time: DateTime, pub last_heartbeat: DateTime, pub tasks_completed: u32, pub uptime_percentage: f64, pub status: AgentInstanceStatus, } /// Agent instance status #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum AgentInstanceStatus { Running, Stopped, Error, } // ============================================================================ // User Models // ============================================================================ /// User model #[derive(Debug, Clone, Serialize, Deserialize)] pub struct User { #[serde(skip_serializing_if = "Option::is_none")] pub id: Option, pub email: String, pub username: String, #[serde(skip_serializing)] pub password_hash: String, #[serde(default)] pub roles: Vec, pub created_at: DateTime, pub updated_at: DateTime, } // ============================================================================ // Workflow Models // ============================================================================ /// Workflow definition #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Workflow { #[serde(skip_serializing_if = "Option::is_none")] pub id: Option, pub tenant_id: String, pub name: String, pub description: Option, pub status: WorkflowStatus, pub definition: serde_json::Value, pub created_at: DateTime, pub updated_at: DateTime, } /// Workflow status #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum WorkflowStatus { Draft, Active, Paused, Completed, Failed, } /// Workflow step execution #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WorkflowStep { #[serde(skip_serializing_if = "Option::is_none")] pub id: Option, pub workflow_id: String, pub step_id: String, pub step_name: String, pub agent_id: Option, pub status: WorkflowStepStatus, pub result: Option, pub error_message: Option, pub started_at: Option>, pub completed_at: Option>, pub created_at: DateTime, } /// Workflow step status #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum WorkflowStepStatus { Pending, InProgress, Completed, Failed, Skipped, } // ============================================================================ // Document Models (RAG) // ============================================================================ /// Document for RAG system #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Document { #[serde(skip_serializing_if = "Option::is_none")] pub id: Option, pub tenant_id: String, pub project_id: Option, pub title: String, pub content: String, pub content_type: DocumentContentType, #[serde(default)] pub metadata: serde_json::Value, pub embedding: Option>, pub source_path: Option, #[serde(default)] pub tags: Vec, pub created_at: DateTime, pub updated_at: DateTime, } /// Document content type #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum DocumentContentType { Markdown, Code, Text, Json, } // ============================================================================ // Proposal Models (Risk-Based Approval) // ============================================================================ /// Proposal model for task approval gates #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Proposal { #[serde(skip_serializing_if = "Option::is_none")] pub id: Option, pub tenant_id: String, pub project_id: String, pub task_id: String, pub agent_id: String, pub title: String, pub description: Option, pub status: ProposalStatus, pub risk_level: RiskLevel, pub plan_details: PlanDetails, pub created_at: DateTime, pub submitted_at: Option>, pub reviewed_at: Option>, pub executed_at: Option>, } /// Proposal status enumeration #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum ProposalStatus { Proposed, Approved, Rejected, Executed, } /// Risk level for proposals #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(rename_all = "lowercase")] pub enum RiskLevel { Low, Medium, High, } /// Detailed plan information for proposals #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct PlanDetails { pub description: String, pub affected_resources: Vec, pub estimated_cost: Option, pub confidence: f64, pub rollback_strategy: Option, pub metadata: serde_json::Value, } /// Review feedback for proposals #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct ProposalReview { #[serde(skip_serializing_if = "Option::is_none")] pub id: Option, pub proposal_id: String, pub reviewer_id: String, pub feedback: String, pub approved: bool, pub created_at: DateTime, }