Skip to main content

systemprompt_agent/repository/context/
mutations.rs

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