systemprompt_database/repository/
cleanup.rs1use anyhow::Result;
2use sqlx::PgPool;
3
4#[derive(Debug)]
5pub struct CleanupRepository {
6 pool: PgPool,
7}
8
9impl CleanupRepository {
10 pub const fn new(pool: PgPool) -> Self {
11 Self { pool }
12 }
13
14 pub async fn delete_orphaned_logs(&self) -> Result<u64> {
15 let result = sqlx::query!(
16 r#"
17 DELETE FROM logs
18 WHERE user_id IS NOT NULL
19 AND user_id NOT IN (SELECT id FROM users)
20 "#
21 )
22 .execute(&self.pool)
23 .await?;
24 Ok(result.rows_affected())
25 }
26
27 pub async fn delete_orphaned_mcp_executions(&self) -> Result<u64> {
28 let result = sqlx::query!(
29 r#"
30 DELETE FROM mcp_tool_executions
31 WHERE context_id IS NOT NULL
32 AND context_id NOT IN (SELECT context_id FROM user_contexts)
33 "#
34 )
35 .execute(&self.pool)
36 .await?;
37 Ok(result.rows_affected())
38 }
39
40 pub async fn delete_old_logs(&self, days: i32) -> Result<u64> {
41 let cutoff = chrono::Utc::now() - chrono::Duration::days(i64::from(days));
42 let result = sqlx::query!("DELETE FROM logs WHERE timestamp < $1", cutoff)
43 .execute(&self.pool)
44 .await?;
45 Ok(result.rows_affected())
46 }
47
48 pub async fn delete_expired_oauth_tokens(&self) -> Result<u64> {
49 let result = sqlx::query!("DELETE FROM oauth_refresh_tokens WHERE expires_at < NOW()")
50 .execute(&self.pool)
51 .await?;
52 Ok(result.rows_affected())
53 }
54
55 pub async fn delete_expired_oauth_codes(&self) -> Result<u64> {
56 let result = sqlx::query!(
57 "DELETE FROM oauth_auth_codes WHERE expires_at < NOW() OR used_at IS NOT NULL"
58 )
59 .execute(&self.pool)
60 .await?;
61 Ok(result.rows_affected())
62 }
63}