1mod continuous;
25mod mutation;
26mod prioritize;
27mod rules;
28#[cfg(feature = "webhook")]
29pub mod server;
30mod signal;
31mod source;
32
33pub use continuous::*;
34pub use mutation::*;
35pub use prioritize::*;
36pub use rules::*;
37pub use signal::*;
38pub use source::*;
39
40use serde::{Deserialize, Serialize};
41use thiserror::Error;
42
43#[derive(Error, Debug)]
45pub enum IntakeError {
46 #[error("Failed to parse webhook payload: {0}")]
47 ParseError(String),
48
49 #[error("Failed to extract signals: {0}")]
50 SignalExtractionError(String),
51
52 #[error("Failed to create mutation: {0}")]
53 MutationError(String),
54
55 #[error("Configuration error: {0}")]
56 ConfigError(String),
57
58 #[error("Storage error: {0}")]
59 StorageError(String),
60}
61
62pub type IntakeResult<T> = Result<T, IntakeError>;
64
65#[derive(Clone, Debug, Serialize, Deserialize)]
67pub struct IntakeConfig {
68 pub enabled: bool,
70
71 pub sources: Vec<IntakeSourceConfig>,
73
74 pub signal_extraction: SignalExtractionConfig,
76
77 pub rate_limit: RateLimitConfig,
79}
80
81impl Default for IntakeConfig {
82 fn default() -> Self {
83 Self {
84 enabled: true,
85 sources: vec![],
86 signal_extraction: SignalExtractionConfig::default(),
87 rate_limit: RateLimitConfig::default(),
88 }
89 }
90}
91
92#[derive(Clone, Debug, Serialize, Deserialize)]
94pub struct IntakeSourceConfig {
95 pub source_type: String,
97
98 pub enabled: bool,
100
101 pub config: serde_json::Value,
103}
104
105#[derive(Clone, Debug, Serialize, Deserialize)]
107pub struct SignalExtractionConfig {
108 pub min_confidence: f32,
110
111 pub max_signals: usize,
113
114 pub enable_pattern_learning: bool,
116}
117
118impl Default for SignalExtractionConfig {
119 fn default() -> Self {
120 Self {
121 min_confidence: 0.5,
122 max_signals: 10,
123 enable_pattern_learning: false,
124 }
125 }
126}
127
128#[derive(Clone, Debug, Serialize, Deserialize)]
130pub struct RateLimitConfig {
131 pub max_requests_per_minute: usize,
133
134 pub max_concurrent: usize,
136
137 pub backoff_seconds: u64,
139}
140
141impl Default for RateLimitConfig {
142 fn default() -> Self {
143 Self {
144 max_requests_per_minute: 60,
145 max_concurrent: 10,
146 backoff_seconds: 60,
147 }
148 }
149}
150
151pub fn generate_intake_id(prefix: &str) -> String {
153 let uuid = uuid::Uuid::new_v4();
154 format!("{}-{}", prefix, uuid)
155}
156
157#[cfg(test)]
158mod tests {
159 use super::*;
160
161 #[test]
162 fn test_generate_intake_id() {
163 let id = generate_intake_id("intake");
164 assert!(id.starts_with("intake-"));
165 }
166
167 #[test]
168 fn test_default_config() {
169 let config = IntakeConfig::default();
170 assert!(config.enabled);
171 assert!(config.sources.is_empty());
172 }
173}