systemprompt_agent/repository/context/
mutations.rs1use chrono::Utc;
2
3use super::ContextRepository;
4use systemprompt_identifiers::{ContextId, SessionId, UserId};
5use systemprompt_traits::RepositoryError;
6
7impl ContextRepository {
8 pub async fn create_context(
9 &self,
10 user_id: &UserId,
11 session_id: Option<&SessionId>,
12 name: &str,
13 ) -> Result<ContextId, RepositoryError> {
14 let context_id = ContextId::generate();
15 let pool = self.get_pg_pool()?;
16 let now = Utc::now();
17 let session_id_str = session_id.map(SessionId::as_str);
18
19 sqlx::query!(
20 "INSERT INTO user_contexts (context_id, user_id, session_id, name, created_at, \
21 updated_at)
22 VALUES ($1, $2, $3, $4, $5, $5)",
23 context_id.as_str(),
24 user_id.as_str(),
25 session_id_str,
26 name,
27 now
28 )
29 .execute(pool.as_ref())
30 .await
31 .map_err(|e| RepositoryError::database(e))?;
32
33 Ok(context_id)
34 }
35
36 pub async fn validate_context_ownership(
37 &self,
38 context_id: &ContextId,
39 user_id: &UserId,
40 ) -> Result<(), RepositoryError> {
41 let pool = self.get_pg_pool()?;
42
43 let result = sqlx::query_scalar!(
44 "SELECT context_id FROM user_contexts WHERE context_id = $1 AND user_id = $2",
45 context_id.as_str(),
46 user_id.as_str()
47 )
48 .fetch_optional(pool.as_ref())
49 .await
50 .map_err(|e| RepositoryError::database(e))?;
51
52 match result {
53 Some(_) => Ok(()),
54 None => Err(RepositoryError::NotFound(format!(
55 "Context {} not found or user {} does not have access",
56 context_id, user_id
57 ))),
58 }
59 }
60
61 pub async fn update_context_name(
62 &self,
63 context_id: &ContextId,
64 user_id: &UserId,
65 name: &str,
66 ) -> Result<(), RepositoryError> {
67 let pool = self.get_pg_pool()?;
68 let now = Utc::now();
69
70 let result = sqlx::query!(
71 "UPDATE user_contexts SET name = $1, updated_at = $2
72 WHERE context_id = $3 AND user_id = $4",
73 name,
74 now,
75 context_id.as_str(),
76 user_id.as_str()
77 )
78 .execute(pool.as_ref())
79 .await
80 .map_err(|e| RepositoryError::database(e))?;
81
82 if result.rows_affected() == 0 {
83 return Err(RepositoryError::NotFound(format!(
84 "Context {} not found for user {}",
85 context_id, user_id
86 )));
87 }
88
89 Ok(())
90 }
91
92 pub async fn delete_context(
93 &self,
94 context_id: &ContextId,
95 user_id: &UserId,
96 ) -> Result<(), RepositoryError> {
97 let pool = self.get_pg_pool()?;
98
99 let result = sqlx::query!(
100 "DELETE FROM user_contexts WHERE context_id = $1 AND user_id = $2",
101 context_id.as_str(),
102 user_id.as_str()
103 )
104 .execute(pool.as_ref())
105 .await
106 .map_err(|e| RepositoryError::database(e))?;
107
108 if result.rows_affected() == 0 {
109 return Err(RepositoryError::NotFound(format!(
110 "Context {} not found for user {}",
111 context_id, user_id
112 )));
113 }
114
115 Ok(())
116 }
117}