//! 清理过期 Refresh Token Worker use async_trait::async_trait; use sqlx::PgPool; use serde::{Serialize, Deserialize}; use crate::error::SaasResult; use super::Worker; #[derive(Debug, Serialize, Deserialize)] pub struct CleanupRefreshTokensArgs; pub struct CleanupRefreshTokensWorker; #[async_trait] impl Worker for CleanupRefreshTokensWorker { type Args = CleanupRefreshTokensArgs; fn name(&self) -> &str { "cleanup_refresh_tokens" } async fn perform(&self, db: &PgPool, _args: Self::Args) -> SaasResult<()> { let now = chrono::Utc::now(); let result = sqlx::query( "DELETE FROM refresh_tokens WHERE expires_at::timestamptz < $1 OR used_at IS NOT NULL" ) .bind(&now) .execute(db) .await?; if result.rows_affected() > 0 { tracing::info!("Cleaned up {} expired/used refresh tokens", result.rows_affected()); } Ok(()) } }