1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Job {
7 pub id: Uuid,
8 pub client_id: Option<Uuid>, pub agent_id: Option<Uuid>,
10 #[serde(default = "default_creator_type")]
11 pub creator_type: String, pub agent_creator_id: Option<Uuid>, pub title: String,
14 pub description: String,
15 pub task_type: String,
16 pub required_skills: Vec<String>,
17 pub complexity: String,
18 pub budget_min: f64,
19 pub budget_max: f64,
20 pub final_price: Option<f64>,
21 pub deadline: Option<DateTime<Utc>>,
22 pub bid_deadline: Option<DateTime<Utc>>,
23 pub urgency: String,
24 pub status: String,
25 pub created_at: DateTime<Utc>,
26}
27
28fn default_creator_type() -> String {
29 "client".to_string()
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct JobWithDetails {
34 #[serde(flatten)]
35 pub job: Job,
36 pub client_name: Option<String>,
37 pub agent_creator_name: Option<String>,
38 pub creator_name: String,
39 pub agent_name: Option<String>,
40 pub bid_count: i64,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct CreateJobRequest {
46 pub title: String,
47 pub description: String,
48 pub task_type: String,
49 pub required_skills: Vec<String>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub complexity: Option<String>,
52 pub budget_min: f64,
53 pub budget_max: f64,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub deadline: Option<DateTime<Utc>>,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub bid_deadline: Option<DateTime<Utc>>,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub urgency: Option<String>,
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct PublishJobResponse {
65 pub job_id: Uuid,
66 pub escrow_pda: String,
67 pub transaction: String,
68 pub amount_usdc: f64,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct SelectBidRequest {
74 pub bid_id: Uuid,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct ApproveJobResponse {
80 pub completed: bool,
81 pub signature: String,
82 pub agent_payout: f64,
83 pub platform_fee: f64,
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct Bid {
88 pub id: Uuid,
89 pub job_id: Uuid,
90 pub agent_id: Uuid,
91 pub bid_amount: f64,
92 pub estimated_hours: Option<f64>,
93 pub estimated_completion: Option<DateTime<Utc>>,
94 pub proposal: String,
95 pub approach: Option<String>,
96 pub status: String,
97 pub revision_count: i32,
98 pub created_at: DateTime<Utc>,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct SubmitBidRequest {
103 pub bid_amount: f64,
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub estimated_hours: Option<f64>,
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub estimated_completion: Option<DateTime<Utc>>,
108 pub proposal: String,
109 #[serde(skip_serializing_if = "Option::is_none")]
110 pub approach: Option<String>,
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
114pub struct SandboxSession {
115 pub job_id: Uuid,
116 pub agent_id: Uuid,
117 pub token: String,
118 pub started_at: DateTime<Utc>,
119 pub expires_at: DateTime<Utc>,
120 pub container_id: Option<String>,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct ProgressUpdate {
125 pub job_id: Uuid,
126 pub progress_percent: u8,
127 pub status_message: String,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct JobResults {
132 pub job_id: Uuid,
133 pub results: serde_json::Value,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct AgentReputation {
138 pub agent_id: Uuid,
139 pub avg_rating: f64,
140 pub total_ratings: i32,
141 pub completion_rate: f64,
142 pub completed_jobs: i32,
143 pub job_success_score: f64,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct JobListQuery {
148 #[serde(skip_serializing_if = "Option::is_none")]
149 pub status: Option<String>,
150 #[serde(skip_serializing_if = "Option::is_none")]
151 pub task_type: Option<String>,
152 #[serde(skip_serializing_if = "Option::is_none")]
153 pub skills: Option<String>,
154 #[serde(skip_serializing_if = "Option::is_none")]
155 pub min_budget: Option<f64>,
156 #[serde(skip_serializing_if = "Option::is_none")]
157 pub max_budget: Option<f64>,
158 #[serde(skip_serializing_if = "Option::is_none")]
159 pub page: Option<i64>,
160 #[serde(skip_serializing_if = "Option::is_none")]
161 pub limit: Option<i64>,
162}
163
164impl Default for JobListQuery {
165 fn default() -> Self {
166 Self {
167 status: Some("open".to_string()),
168 task_type: None,
169 skills: None,
170 min_budget: None,
171 max_budget: None,
172 page: Some(1),
173 limit: Some(20),
174 }
175 }
176}
177
178#[derive(Debug, Clone, Serialize, Deserialize)]
184pub struct X402PaymentRequest {
185 pub network: String,
186 pub token: String,
187 pub amount: u64,
188 pub recipient: String,
189 pub nonce: String,
190 pub expires: u64,
191 pub description: Option<String>,
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct X402PaymentProof {
197 pub tx_hash: String,
198 pub nonce: String,
199 pub payer: String,
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize)]
204pub struct X402ErrorResponse {
205 pub error: String,
206 pub message: String,
207 pub payment: Option<X402PaymentRequest>,
208}
209
210#[derive(Debug, Clone, Serialize, Deserialize)]
216pub struct EscrowFundResult {
217 pub escrow_pda: String,
218 pub transaction: String,
219 pub amount_usdc: f64,
220}