1#![allow(unused_variables)] use axum::{extract::Json, http::StatusCode, response::IntoResponse};
15use chrono::{DateTime, Utc};
16use serde::{Deserialize, Serialize};
17use serde_json::Value;
18use std::collections::HashMap;
19use uuid::Uuid;
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct UserSettings {
24 pub user_id: Uuid,
26 pub version: u64,
28 pub last_sync: DateTime<Utc>,
30 pub thinktool: ThinkToolSettings,
32 pub cli: CliSettings,
34 pub editor: EditorSettings,
36 pub notifications: NotificationSettings,
38 pub custom: HashMap<String, Value>,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, Default)]
43pub struct ThinkToolSettings {
44 pub default_profile: String,
46 pub preferred_provider: Option<String>,
48 pub confidence_threshold: f64,
50 pub verbose_output: bool,
52 pub custom_tools: HashMap<String, Value>,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize, Default)]
57pub struct CliSettings {
58 pub output_format: String,
60 pub color_enabled: bool,
62 pub pager: Option<String>,
64 pub history_path: Option<String>,
66 pub max_history: usize,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize, Default)]
71pub struct EditorSettings {
72 pub editor: String,
74 pub tab_width: u8,
76 pub use_spaces: bool,
78 pub auto_save: bool,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize, Default)]
83pub struct NotificationSettings {
84 pub email_enabled: bool,
86 pub push_enabled: bool,
88 pub categories: HashMap<String, bool>,
90}
91
92impl Default for UserSettings {
93 fn default() -> Self {
94 Self {
95 user_id: Uuid::nil(),
96 version: 1,
97 last_sync: Utc::now(),
98 thinktool: ThinkToolSettings {
99 default_profile: "balanced".to_string(),
100 preferred_provider: None,
101 confidence_threshold: 0.8,
102 verbose_output: false,
103 custom_tools: HashMap::new(),
104 },
105 cli: CliSettings {
106 output_format: "text".to_string(),
107 color_enabled: true,
108 pager: Some("less".to_string()),
109 history_path: None,
110 max_history: 1000,
111 },
112 editor: EditorSettings {
113 editor: std::env::var("EDITOR").unwrap_or_else(|_| "vim".to_string()),
114 tab_width: 4,
115 use_spaces: true,
116 auto_save: false,
117 },
118 notifications: NotificationSettings::default(),
119 custom: HashMap::new(),
120 }
121 }
122}
123
124pub struct SettingsService {
126 }
128
129impl SettingsService {
130 pub fn new() -> Self {
131 Self {}
132 }
133
134 pub async fn get_settings(&self, user_id: Uuid) -> Result<UserSettings, SettingsError> {
136 Ok(UserSettings {
138 user_id,
139 ..Default::default()
140 })
141 }
142
143 pub async fn update_settings(
145 &self,
146 user_id: Uuid,
147 settings: UserSettings,
148 client_version: u64,
149 ) -> Result<UserSettings, SettingsError> {
150 Err(SettingsError::NotFound)
155 }
156
157 pub async fn get_diff(
159 &self,
160 user_id: Uuid,
161 from_version: u64,
162 ) -> Result<SettingsDiff, SettingsError> {
163 Err(SettingsError::NotFound)
165 }
166}
167
168impl Default for SettingsService {
169 fn default() -> Self {
170 Self::new()
171 }
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
176pub struct SettingsDiff {
177 pub from_version: u64,
178 pub to_version: u64,
179 pub changes: Vec<SettingsChange>,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
184pub struct SettingsChange {
185 pub path: String,
187 pub operation: ChangeOperation,
189 pub old_value: Option<Value>,
191 pub new_value: Option<Value>,
193 pub timestamp: DateTime<Utc>,
195}
196
197#[derive(Debug, Clone, Serialize, Deserialize)]
199#[serde(rename_all = "lowercase")]
200pub enum ChangeOperation {
201 Set,
203 Delete,
205 Merge,
207}
208
209#[derive(Debug, thiserror::Error)]
211pub enum SettingsError {
212 #[error("Settings not found")]
214 NotFound,
215 #[error("Version conflict: server has version {server}, client sent {client}")]
217 VersionConflict {
218 server: u64,
220 client: u64,
222 },
223 #[error("Invalid settings: {0}")]
225 ValidationError(String),
226 #[error("Database error: {0}")]
228 DatabaseError(String),
229}
230
231pub mod handlers {
233 use super::*;
234
235 pub async fn get_settings() -> impl IntoResponse {
237 let settings = UserSettings::default();
238 (StatusCode::OK, Json(settings))
239 }
240
241 pub async fn update_settings(Json(settings): Json<UserSettings>) -> impl IntoResponse {
243 (StatusCode::OK, Json(settings))
245 }
246
247 pub async fn sync_settings() -> impl IntoResponse {
249 (
250 StatusCode::OK,
251 Json(serde_json::json!({
252 "success": true,
253 "synced_at": Utc::now(),
254 "version": 1
255 })),
256 )
257 }
258}