use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use sqlx::{FromRow, PgPool}; use uuid::Uuid; #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct ActivityLog { pub id: Uuid, pub actor_id: Uuid, pub actor_type: String, pub entity_id: Uuid, pub entity_type: String, pub action: String, pub metadata: Option, pub ip_address: Option, pub user_agent: Option, pub created_at: DateTime, } pub struct ActivityLogRepository; impl ActivityLogRepository { pub async fn create( pool: &PgPool, actor_id: Uuid, actor_type: &str, entity_id: Uuid, entity_type: &str, action: &str, metadata: Option, ) -> Result { sqlx::query_as::<_, ActivityLog>( r#" INSERT INTO activity_logs (actor_id, actor_type, entity_id, entity_type, action, metadata) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id, actor_id, actor_type, entity_id, entity_type, action, metadata, ip_address, user_agent, created_at "# ) .bind(actor_id) .bind(actor_type) .bind(entity_id) .bind(entity_type) .bind(action) .bind(metadata) .fetch_one(pool) .await } pub async fn list_for_entity( pool: &PgPool, entity_type: &str, entity_id: Uuid, ) -> Result, sqlx::Error> { sqlx::query_as::<_, ActivityLog>( r#" SELECT id, actor_id, actor_type, entity_id, entity_type, action, metadata, ip_address, user_agent, created_at FROM activity_logs WHERE entity_type = $1 AND entity_id = $2 ORDER BY created_at DESC "# ) .bind(entity_type) .bind(entity_id) .fetch_all(pool) .await } }