diff --git a/src-tauri/src/db.rs b/src-tauri/src/db.rs index f372a34..b6cc478 100644 --- a/src-tauri/src/db.rs +++ b/src-tauri/src/db.rs @@ -27,6 +27,17 @@ pub struct Session { pub last_message: Option, } +/// Eine Chat-Nachricht +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct ChatMessage { + pub id: String, + pub session_id: String, + pub role: String, // "user", "assistant", "system" + pub content: String, + pub model: Option, + pub timestamp: String, +} + /// Datenbank-Wrapper pub struct Database { conn: Connection, @@ -141,6 +152,18 @@ impl Database { value TEXT NOT NULL, updated_at TEXT NOT NULL ); + + -- Chat-Nachrichten + CREATE TABLE IF NOT EXISTS messages ( + id TEXT PRIMARY KEY, + session_id TEXT NOT NULL, + role TEXT NOT NULL, + content TEXT NOT NULL, + model TEXT, + timestamp TEXT NOT NULL, + FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE + ); + CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id, timestamp); ", )?; Ok(()) @@ -488,10 +511,58 @@ impl Database { /// Löscht eine Session pub fn delete_session(&self, id: &str) -> SqlResult<()> { + // Erst Nachrichten löschen (wegen Foreign Key) + self.conn.execute("DELETE FROM messages WHERE session_id = ?1", params![id])?; self.conn.execute("DELETE FROM sessions WHERE id = ?1", params![id])?; Ok(()) } + // ============ Messages ============ + + /// Speichert eine Nachricht + pub fn save_message(&self, msg: &ChatMessage) -> SqlResult<()> { + self.conn.execute( + "INSERT OR REPLACE INTO messages (id, session_id, role, content, model, timestamp) + VALUES (?1, ?2, ?3, ?4, ?5, ?6)", + params![ + msg.id, + msg.session_id, + msg.role, + msg.content, + msg.model, + msg.timestamp, + ], + )?; + Ok(()) + } + + /// Lädt alle Nachrichten einer Session + pub fn load_messages(&self, session_id: &str) -> SqlResult> { + let mut stmt = self.conn.prepare( + "SELECT id, session_id, role, content, model, timestamp + FROM messages WHERE session_id = ?1 ORDER BY timestamp ASC" + )?; + + let messages = stmt.query_map(params![session_id], |row| { + Ok(ChatMessage { + id: row.get(0)?, + session_id: row.get(1)?, + role: row.get(2)?, + content: row.get(3)?, + model: row.get(4)?, + timestamp: row.get(5)?, + }) + })?.collect::>>()?; + + Ok(messages) + } + + /// Löscht alle Nachrichten einer Session + pub fn clear_messages(&self, session_id: &str) -> SqlResult<()> { + self.conn.execute("DELETE FROM messages WHERE session_id = ?1", params![session_id])?; + Ok(()) + } + // ============ Settings ============ /// Speichert eine Einstellung @@ -637,3 +708,27 @@ pub async fn get_all_settings(app: AppHandle) -> Result, S let db = state.lock().unwrap(); db.get_all_settings().map_err(|e| e.to_string()) } + +/// Nachricht speichern +#[tauri::command] +pub async fn save_message(app: AppHandle, message: ChatMessage) -> Result<(), String> { + let state = app.state::(); + let db = state.lock().unwrap(); + db.save_message(&message).map_err(|e| e.to_string()) +} + +/// Nachrichten einer Session laden +#[tauri::command] +pub async fn load_messages(app: AppHandle, session_id: String) -> Result, String> { + let state = app.state::(); + let db = state.lock().unwrap(); + db.load_messages(&session_id).map_err(|e| e.to_string()) +} + +/// Alle Nachrichten einer Session löschen +#[tauri::command] +pub async fn clear_messages(app: AppHandle, session_id: String) -> Result<(), String> { + let state = app.state::(); + let db = state.lock().unwrap(); + db.clear_messages(&session_id).map_err(|e| e.to_string()) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 33dd42a..d98509f 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -57,6 +57,10 @@ pub fn run() { session::resume_session, session::get_active_session, session::set_claude_session_id, + // Messages + db::save_message, + db::load_messages, + db::clear_messages, ]) .setup(|app| { let handle = app.handle().clone(); diff --git a/src/lib/components/ChatPanel.svelte b/src/lib/components/ChatPanel.svelte index 6f97f5c..67b8e58 100644 --- a/src/lib/components/ChatPanel.svelte +++ b/src/lib/components/ChatPanel.svelte @@ -1,8 +1,9 @@