1use fukurow_core::model::{CyberEvent, SecurityAction};
4use fukurow_engine::ReasonerError;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Serialize, Deserialize)]
9pub struct ApiResponse<T> {
10 pub success: bool,
11 pub data: Option<T>,
12 pub error: Option<String>,
13 pub timestamp: i64,
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 timestamp: chrono::Utc::now().timestamp(),
23 }
24 }
25
26 pub fn error(message: String) -> Self {
27 Self {
28 success: false,
29 data: None,
30 error: Some(message),
31 timestamp: chrono::Utc::now().timestamp(),
32 }
33 }
34}
35
36#[derive(Debug, Serialize, Deserialize)]
38pub struct SubmitEventRequest {
39 pub event: CyberEvent,
40}
41
42#[derive(Debug, Deserialize)]
44pub struct ReasoningRequest {
45 pub include_details: Option<bool>,
46}
47
48#[derive(Debug, Serialize)]
50pub struct ReasoningResponse {
51 pub actions: Vec<SecurityAction>,
52 pub execution_time_ms: u64,
53 pub event_count: usize,
54}
55
56#[derive(Debug, Deserialize)]
58pub struct GraphQueryRequest {
59 pub subject: Option<String>,
60 pub predicate: Option<String>,
61 pub object: Option<String>,
62 pub graph_name: Option<String>,
63}
64
65#[derive(Debug, Serialize)]
67pub struct GraphQueryResponse {
68 pub triples: Vec<fukurow_core::model::Triple>,
69 pub count: usize,
70}
71
72#[derive(Debug, Serialize)]
74pub struct HealthResponse {
75 pub status: String,
76 pub version: String,
77 pub uptime_seconds: u64,
78}
79
80#[derive(Debug, Serialize)]
82pub struct StatsResponse {
83 pub total_events: usize,
84 pub total_actions: usize,
85 pub uptime_seconds: u64,
86 pub memory_usage_mb: Option<f64>,
87}
88
89#[derive(Debug, Deserialize)]
91pub struct AddRuleRequest {
92 pub rule: fukurow_core::model::InferenceRule,
93}
94
95#[derive(Debug, Serialize)]
97pub struct RulesResponse {
98 pub rules: Vec<fukurow_core::model::InferenceRule>,
99 pub count: usize,
100}
101
102#[derive(Debug, Serialize)]
104pub struct ThreatIntelResponse {
105 pub indicators_count: usize,
106 pub sources_count: usize,
107 pub last_updated: i64,
108 pub statistics: std::collections::HashMap<String, usize>,
109}
110
111#[derive(Debug, thiserror::Error)]
113pub enum ApiError {
114 #[error("Invalid request: {0}")]
115 InvalidRequest(String),
116
117 #[error("Event processing error: {0}")]
118 EventProcessingError(String),
119
120 #[error("Reasoning error: {0}")]
121 ReasoningError(String),
122
123 #[error("Graph operation error: {0}")]
124 GraphError(String),
125
126 #[error("Internal server error: {0}")]
127 InternalError(String),
128}
129
130impl From<ReasonerError> for ApiError {
131 fn from(err: ReasonerError) -> Self {
132 match err {
133 ReasonerError::GraphError(_) => ApiError::GraphError(err.to_string()),
134 ReasonerError::RuleError(_) => ApiError::ReasoningError(err.to_string()),
135 ReasonerError::ReasoningError(_) => ApiError::ReasoningError(err.to_string()),
136 ReasonerError::StoreError(_) => ApiError::InternalError(err.to_string()),
137 }
138 }
139}
140
141impl From<anyhow::Error> for ApiError {
142 fn from(err: anyhow::Error) -> Self {
143 ApiError::InternalError(err.to_string())
144 }
145}