Skip to main content

fastskill_core/http/
models.rs

1//! Request and response models for the HTTP API
2
3use serde::{Deserialize, Serialize};
4use validator::Validate;
5
6/// Generic API response wrapper
7#[derive(Debug, Serialize, Clone)]
8#[serde(rename_all = "camelCase")]
9pub struct ApiResponse<T> {
10    pub success: bool,
11    pub data: Option<T>,
12    pub error: Option<ErrorResponse>,
13    pub meta: Option<ResponseMeta>,
14}
15
16impl<T> ApiResponse<T> {
17    pub fn success(data: T) -> Self {
18        Self {
19            success: true,
20            data: Some(data),
21            error: None,
22            meta: None,
23        }
24    }
25
26    pub fn success_with_meta(data: T, meta: ResponseMeta) -> Self {
27        Self {
28            success: true,
29            data: Some(data),
30            error: None,
31            meta: Some(meta),
32        }
33    }
34
35    pub fn error(error: ErrorResponse) -> Self {
36        Self {
37            success: false,
38            data: None,
39            error: Some(error),
40            meta: None,
41        }
42    }
43}
44
45/// Response metadata
46#[derive(Debug, Serialize, Clone)]
47#[serde(rename_all = "camelCase")]
48pub struct ResponseMeta {
49    pub total_count: Option<i64>,
50    pub page: Option<i32>,
51    pub page_size: Option<i32>,
52    pub has_next: Option<bool>,
53}
54
55/// Error response
56#[derive(Debug, Serialize, Clone)]
57#[serde(rename_all = "camelCase")]
58pub struct ErrorResponse {
59    pub code: String,
60    pub message: String,
61    pub details: Option<serde_json::Value>,
62}
63
64/// Skill definition for API responses
65#[derive(Debug, Serialize, Clone)]
66#[serde(rename_all = "camelCase")]
67pub struct SkillResponse {
68    pub id: String,
69    pub name: String,
70    pub description: String,
71    pub metadata: serde_json::Value,
72    pub created_at: Option<String>,
73    pub updated_at: Option<String>,
74}
75
76/// Skill list response
77#[derive(Debug, Serialize, Clone)]
78#[serde(rename_all = "camelCase")]
79pub struct SkillsListResponse {
80    pub skills: Vec<SkillResponse>,
81    pub count: usize,
82    pub total: usize,
83}
84
85/// Skill creation/update request
86#[derive(Debug, Deserialize, Validate, Clone)]
87#[serde(rename_all = "camelCase")]
88pub struct SkillRequest {
89    #[validate(length(min = 1, max = 100))]
90    pub name: String,
91
92    #[validate(length(min = 1, max = 1000))]
93    pub description: String,
94
95    pub metadata: serde_json::Value,
96}
97
98/// Search request
99#[derive(Debug, Deserialize, Validate, Clone)]
100#[serde(rename_all = "camelCase")]
101pub struct SearchRequest {
102    #[validate(length(min = 1, max = 1000))]
103    pub query: String,
104
105    #[validate(range(min = 1, max = 50))]
106    pub limit: Option<i32>,
107
108    pub semantic: Option<bool>,
109}
110
111/// Search response
112#[derive(Debug, Serialize, Clone)]
113#[serde(rename_all = "camelCase")]
114pub struct SearchResponse {
115    pub skills: Vec<SkillMatchResponse>,
116    pub count: usize,
117    pub query: String,
118}
119
120/// Skill match in search results
121#[derive(Debug, Serialize, Clone)]
122#[serde(rename_all = "camelCase")]
123pub struct SkillMatchResponse {
124    pub skill: SkillResponse,
125    pub score: f32,
126    pub relevance: String,
127}
128
129/// Reindex request
130#[derive(Debug, Deserialize, Validate, Clone)]
131#[serde(rename_all = "camelCase")]
132pub struct ReindexRequest {
133    pub force: Option<bool>,
134    pub skill_ids: Option<Vec<String>>,
135}
136
137/// Reindex response
138#[derive(Debug, Serialize, Clone)]
139#[serde(rename_all = "camelCase")]
140pub struct ReindexResponse {
141    pub success_count: usize,
142    pub error_count: usize,
143    pub total_processed: usize,
144    pub duration_ms: u64,
145}
146
147/// Status response
148#[derive(Debug, Serialize, Clone)]
149#[serde(rename_all = "camelCase")]
150pub struct StatusResponse {
151    pub status: String,
152    pub version: String,
153    pub skills_count: usize,
154    pub storage_path: String,
155    pub hot_reload_enabled: bool,
156    pub uptime_seconds: u64,
157}
158
159/// Source response for registry
160#[derive(Debug, Serialize, Clone)]
161#[serde(rename_all = "camelCase")]
162pub struct SourceResponse {
163    pub name: String,
164    pub source_type: String,
165    pub url: Option<String>,
166    pub path: Option<String>,
167    pub supports_marketplace: bool,
168}
169
170/// Marketplace skill response
171#[derive(Debug, Serialize, Clone)]
172#[serde(rename_all = "camelCase")]
173pub struct MarketplaceSkillResponse {
174    pub id: String,
175    pub name: String,
176    pub description: String,
177    pub version: String,
178    pub author: Option<String>,
179    pub download_url: Option<String>,
180    pub source_name: String,
181    pub installed: bool,
182}
183
184/// Source skills response
185#[derive(Debug, Serialize, Clone)]
186#[serde(rename_all = "camelCase")]
187pub struct SourceSkillsResponse {
188    pub source_name: String,
189    pub skills: Vec<MarketplaceSkillResponse>,
190    pub count: usize,
191}
192
193/// Registry skills response (all sources)
194#[derive(Debug, Serialize, Clone)]
195#[serde(rename_all = "camelCase")]
196pub struct RegistrySkillsResponse {
197    pub sources: Vec<SourceSkillsResponse>,
198    pub total_skills: usize,
199    pub total_sources: usize,
200}
201
202/// Manifest skill response
203#[derive(Debug, Serialize, Clone)]
204#[serde(rename_all = "camelCase")]
205pub struct ManifestSkillResponse {
206    pub id: String,
207    pub version: Option<String>,
208    pub groups: Vec<String>,
209    pub editable: bool,
210    pub source_type: String,
211}
212
213/// Add skill to manifest request
214#[derive(Debug, Deserialize, Validate, Clone)]
215#[serde(rename_all = "camelCase")]
216pub struct AddSkillRequest {
217    #[validate(length(min = 1))]
218    pub skill_id: String,
219
220    #[validate(length(min = 1))]
221    pub source_name: String,
222
223    pub groups: Option<Vec<String>>,
224    pub editable: Option<bool>,
225}
226
227/// Update skill in manifest request
228#[derive(Debug, Deserialize, Validate, Clone)]
229#[serde(rename_all = "camelCase")]
230pub struct UpdateSkillRequest {
231    pub groups: Option<Vec<String>>,
232    pub editable: Option<bool>,
233    pub version: Option<String>,
234}