turul_mcp_session_storage/session_view.rs
1// SessionView trait for middleware access to sessions
2//!
3//! Minimal interface for middleware to access session state without depending on
4//! the concrete SessionContext implementation in turul-mcp-server.
5
6use async_trait::async_trait;
7use serde_json::Value;
8
9/// Minimal session interface for middleware access
10///
11/// This trait provides a read-write view of session state for middleware
12/// without exposing the full SessionContext implementation details.
13///
14/// # Silent Write Failures
15///
16/// **IMPORTANT**: `set_state` and `set_metadata` currently always return `Ok(())`.
17/// The underlying storage may log errors but does not propagate them to middleware.
18/// This design prevents middleware from blocking request processing due to storage issues.
19///
20/// # Example
21///
22/// ```rust,no_run
23/// use turul_mcp_session_storage::SessionView;
24/// use serde_json::json;
25///
26/// async fn middleware_example(session: &dyn SessionView) {
27/// // Read session state
28/// if let Ok(Some(counter)) = session.get_state("request_count").await {
29/// println!("Session {}: {} requests", session.session_id(), counter);
30/// }
31///
32/// // Write session state
33/// let _ = session.set_state("last_access", json!("2025-10-05")).await;
34/// }
35/// ```
36#[async_trait]
37pub trait SessionView: Send + Sync {
38 /// Get the unique session identifier
39 ///
40 /// # Returns
41 ///
42 /// The session ID as a string reference. Typically a UUID v7 for temporal ordering.
43 fn session_id(&self) -> &str;
44
45 /// Get a state value from the session
46 ///
47 /// # Parameters
48 ///
49 /// - `key`: The state key to retrieve
50 ///
51 /// # Returns
52 ///
53 /// - `Ok(Some(value))`: State value exists
54 /// - `Ok(None)`: State key not found
55 /// - `Err(error)`: Storage error occurred
56 async fn get_state(&self, key: &str) -> Result<Option<Value>, String>;
57
58 /// Set a state value in the session
59 ///
60 /// # Parameters
61 ///
62 /// - `key`: The state key to set
63 /// - `value`: The JSON value to store
64 ///
65 /// # Returns
66 ///
67 /// - `Ok(())`: State was successfully set (or error was logged silently)
68 /// - `Err(error)`: Storage error occurred
69 ///
70 /// **Note**: Current implementation always returns `Ok(())` even if underlying
71 /// storage fails. Errors are logged but not propagated.
72 async fn set_state(&self, key: &str, value: Value) -> Result<(), String>;
73
74 /// Get a metadata value from the session
75 ///
76 /// Metadata is typically set during session initialization and provides
77 /// context about the session (client version, capabilities, etc.).
78 ///
79 /// # Parameters
80 ///
81 /// - `key`: The metadata key to retrieve
82 ///
83 /// # Returns
84 ///
85 /// - `Ok(Some(value))`: Metadata value exists
86 /// - `Ok(None)`: Metadata key not found
87 /// - `Err(error)`: Storage error occurred
88 async fn get_metadata(&self, key: &str) -> Result<Option<Value>, String>;
89
90 /// Set a metadata value in the session
91 ///
92 /// # Parameters
93 ///
94 /// - `key`: The metadata key to set
95 /// - `value`: The JSON value to store
96 ///
97 /// # Returns
98 ///
99 /// - `Ok(())`: Metadata was successfully set (or error was logged silently)
100 /// - `Err(error)`: Storage error occurred
101 ///
102 /// **Note**: Current implementation always returns `Ok(())` even if underlying
103 /// storage fails. Errors are logged but not propagated.
104 async fn set_metadata(&self, key: &str, value: Value) -> Result<(), String>;
105}