use serde::{Deserialize, Serialize}; use sqlx::prelude::FromRow; use crate::{get_pg, library::user::User}; /// Represents a user event in the database. #[derive(Debug, Clone, Serialize, Deserialize, FromRow)] pub struct Event { /// Unique identifier for this event. pub id: uuid::Uuid, /// Timestamp of when this event occurred. pub time: chrono::DateTime, /// Type of event (e.g. play, stop). pub kind: EventKind, /// Username of the user who performed this action. pub user: String, /// ID of the track associated with this event. pub track: uuid::Uuid, } /// Enum representing different types of events that can occur. #[derive(Debug, Clone, Serialize, Deserialize, sqlx::Type)] #[sqlx(type_name = "event_kind", rename_all = "lowercase")] pub enum EventKind { /// A user started playing a track. Play, /// A user finished playing a track. Played, /// A user stopped playing a track. Stop, } impl Event { /// Creates a new event in the database with the given kind, user, and track. /// /// Returns the newly created event object. pub async fn create(kind: EventKind, user: &User, track: uuid::Uuid) -> Self { sqlx::query_as("INSERT INTO events (kind, \"user\", track) VALUES ($1, $2, $3) RETURNING *") .bind(kind) .bind(&user.username) .bind(track) .fetch_one(get_pg!()) .await .unwrap() } /// Retrieves the latest 300 events performed by a given user. /// /// Returns a vector of event objects. pub async fn get_latest_events_of(u: &User) -> Vec { sqlx::query_as("SELECT * FROM events WHERE \"user\" = $1 ORDER BY time DESC LIMIT 300") .bind(&u.username) .fetch_all(get_pg!()) .await .unwrap() } }